regex (в PHP), чтобы соответствовать &, которые не являются объектами HTML

Вот цель: заменить все автономные амперсанды на & amp; но НЕ заменяют те, которые уже являются частью HTML-объекта, такого как & nbsp ;.

Я думаю, мне нужно регулярное выражение для PHP (желательно для preg_ functions), которое будет соответствовать только автономным амперсандам. Я просто не знаю, как это сделать с preg_replace.

Solutions Collecting From Web of "regex (в PHP), чтобы соответствовать &, которые не являются объектами HTML"

Вы всегда можете запустить html_entity_decode перед запуском htmlentities ? Работает, если только вы не хотите использовать амперсанды (и даже тогда вы можете играть с параметрами кодировки).

Гораздо проще и быстрее, чем регулярное выражение.

PHP htmlentities() имеет аргумент double_encode для этого.

Если вы хотите делать что-то подобное в регулярных выражениях, то отрицательные утверждения полезны:

 preg_replace('/&(?![az#]+;)/i','&',$txt); 

Росс привел меня к хорошему ответу. Вот код, который, кажется, работает достаточно хорошо. Так далеко. 🙂 Целью, опять же, является преобразование HTML в XML, в частности, описание для RSS-каналов. В кратком тестировании, которое я сделал до сих пор (с некоторыми довольно довольно изворотливыми данными), мне удалось взять строки, завернутые в CDATA, и развернуть его. Пропускает проверки. Спасибо, Росс.

 //decode all entities $string=html_entity_decode($string,ENT_COMPAT,'UTF-8'); //entity-encode only &<> and double quotes $string=htmlspecialchars($string,ENT_COMPAT,'UTF-8'); 

Другие – хорошие предложения, и это может быть лучший способ сделать это. Но я подумал, что постараюсь ответить на вопрос, как было задано, – только для того, чтобы предоставить пример регулярного выражения.

Ниже приведена специальная взорванная форма, разрешенная в некоторых двигателях. Конечно, странно, что движок, который позволяет прокомментированные регулярные выражения допускать другие упрощенные выражения, но не как общие. Я добавлю эти упрощенные выражения в parens в комментарии.

 & # an ampersand ( \# # a '#' character [1-9] # followed by a non-zero digit, [0-9]{1,3} # with between 2 and 4 (\d{1,3} or \p{IsDigit}{1,3}) | [A-Za-z] # OR a letter (\p{IsAlpha}) [0-9A-Za-z]+ # followed by letters or numbers (\p{IsAlnum}+) ) ; # all capped with a ';' 

Вы могли бы даже бросить кучу ожидаемых объектов там, чтобы помочь в сканере регулярных выражений.

 & # an ampersand ( amp | apos | gt | lt | nbsp | quot # standard entities | bull | hellip | [lr][ds]quo | [mn]dash | permil # some fancier ones | \# # a '#' character [1-9] # followed by a non-zero digit, [0-9]{1,3} # with between 2 and 4 | [A-Za-z] # OR a letter [0-9A-Za-z]+ # followed by letters or numbers ) ; # all capped with a ';' 

У меня была такая же проблема, изначально использовалась:

 $string = htmlspecialchars($string, ENT_QUOTES, "UTF-8", FALSE); 

Но нужно, чтобы он работал с PHP4 и сочетанием CharSets, в итоге:

 function htmlspecialchars_custom($string) { $string = str_replace("\x05\x06", "", $string); $string = preg_replace("/&([az\d]{2,7}|#\d{2,5});/i", "\x05\x06$1", $string); $string = htmlspecialchars($string, ENT_QUOTES); $string = str_replace("\x05\x06", "&", $string); return $string; } 

Это не идеально, но достаточно хорошо для моих нужд.