Любые подводные камни с этим регулярным выражением, которые соответствуют амперсандам, еще не закодированным - PullRequest
4 голосов
/ 12 марта 2009

В PHP я хочу кодировать амперсанды, которые еще не были закодированы. Я придумал это регулярное выражение

/&(?=[^a])/

Кажется, до сих пор это работает хорошо, но, учитывая, что я не очень большой специалист по регулярным выражениям, я спрашиваю, можно ли увидеть какие-либо потенциальные ловушки в этом регулярном выражении?

По сути, необходимо преобразовать & в &, но оставить & в & как есть (чтобы не получить &)

Спасибо

Обновление

Спасибо за ответы. Кажется, я не думал достаточно широко, чтобы охватить все основы. Это похоже на обычную ловушку самих регулярных выражений (нужно думать обо всех возможностях, которые могут заставить ваше регулярное выражение получать ложные срабатывания). Это точно превосходит мой оригинальный str_replace(' & ', ' & ', $string);:)

Ответы [ 6 ]

17 голосов
/ 12 марта 2009

Еще лучше было бы отрицательное прогнозное утверждение для проверки, за которым не следует

/&(?!amp;)/

Хотя это изменит любые амперсанды, используемые для других сущностей. Если у вас есть вероятность, что у вас есть другие, то как насчет чего-то вроде

/&(?!#?[a-zA-Z0-9]+;)/

Это будет искать амперсанд, но при этом утверждается, что за ним НЕ следует необязательный хэш-символ (для числовых объектов), серия буквенно-цифровых символов и точка с запятой, которая должна охватывать именованных и числовых объектов , таких как &quote; или ª

Тестовый код

$text="It’s 30 ° outside & very hot. T-shirt & shorts needed!";

$text=preg_replace('/&(?!#?[a-z0-9]+;)/', '&', $text);

echo "$text\n";

Который выдаст

It’s 30 ° outside & very hot. T-shirt & shorts needed!

, который легче читать как "На улице 30 °, очень жарко. Требуются футболка и шорты!"

Альтернатива для PHP 5.2.3 +

Как указывает Ионут Дж. Стэн ниже, из PHP 5.2.3 вы можете использовать htmlspecialchars с четвертым параметром false для предотвращения двойного кодирования, например

$text=htmlspecialchars($text,ENT_COMPAT,"UTF-8",false);
2 голосов
/ 12 марта 2009

Если ваша версия PHP> = 5.2.3, вы можете использовать четвертый параметр функции htmlspecialchars . При значении false он не будет преобразовывать существующие объекты.

2 голосов
/ 12 марта 2009

Он будет применяться для любого другого закодированного символа.

1 голос
/ 21 декабря 2010

В Perl это будет:

$content =~ s/&(?!\w+;)/&/g;

В нем используется отрицательное предположение, состоящее из 1 или более символов слова, что означает «амперсанд, за которым не следует один или несколько символов слова и сразу же следует точка с запятой. Хотя использование сочетания клавиш \ w не так безопасно, как определенный диапазон символов для этого конкретного случая. Лучшим вариантом будет:

$content =~ s/&(?![a-z]+;)/&/g;

И на всякий случай в ваших данных есть заглавное животное:

$content =~ s/&(?![a-zA-Z]+;)/&/g;
0 голосов
/ 12 марта 2009

Это потерпит неудачу в случае, когда символ «а» следует за амперсандом, но не «ампер»; как и и и также и яблоко ...

& (?! амп;)

0 голосов
/ 12 марта 2009

Что происходит, когда в вашем документе есть другие объекты? Что произойдет, если вы говорите о сеансе вопросов и ответов?

Я бы выделил амперсанд, а не угадал контекст, а затем использовал бы обратные ссылки в вашей замещающей строке

/(\W)&(\W)/$1&$2/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...