PHP Regexp с тире и амперсандом не работает

#php #regex #ampersand

#php #регулярное выражение #амперсанд

Вопрос:

вот строка:

 $test =  '<a id="test">One amp;amp; -Twoamp;nbsp;-amp;nbsp;Three</a>';
  

И я хотел бы преобразовать эти две строки в 2 разные переменные, такие как:

 $string1 = 'One amp;amp; -Two';
  

и

 $string2 = 'Three';
  

Итак, я использую preg_match_all, но у меня проблема с регулярным выражением:

 preg_match_all('#([-;w ./'d()amp;] ) amp;nbsp;-amp;nbsp;([w  .-] ) #', $test, $matches);
  

Может кто-нибудь объяснить мне, почему это не работает ..? Я не вижу, какое «правило» я здесь не уважаю..

Комментарии:

1. Вы пытаетесь получить значение из html-элемента с помощью регулярного выражения, если да, пожалуйста, используйте dom или простой html dom

2. имейте в виду, что ([-;w ./'d()amp;] ) это инициирует катастрофическое отслеживание назад, если сопоставление не удается

3. У вас также есть много ненужных обратных косых черт, что затрудняет чтение…

4. Посмотрите здесь , регулярное выражение не требуется. На самом деле это первое ) , которое вызывает катастрофическую проблему с возвратом. Последнее в порядке, хотя и совершенно бесполезно (движок знает, как справиться с just /(a ) / ).

5. Вы могли бы использовать regex101.com в качестве первого шага к отладке регулярного выражения, и если вы это сделаете, вы прочтете что-то вроде: Catastrophic backtracking has been detected что является полезной информацией

Ответ №1:

Первое после ) ( ([-;w ./'d()amp;] ) ) вызывает катастрофическую проблему с возвратом (смотрите подробнее об этом здесь), поскольку это случай (a ) типа шаблона, который не является конечным подшаблоном. Удаление этого уже решает проблему.

Последний подшаблон имеет ту же проблему, но не вызывает проблем из-за внутренней оптимизации PCRE.

Кроме того, я думаю, вам здесь не нужно никаких регулярных выражений, используйте explode и strip_tags :

 $test =  '<a id="test">One amp;amp; -Twoamp;nbsp;-amp;nbsp;Three</a>';
$res = explode("amp;nbsp;-amp;nbsp;", strip_tags($test));
echo $res[0]. "n" . $res[1];
  

Смотрите демонстрацию PHP