регулярное выражение (в PHP), чтобы соответствовать и не являются объектами HTML - PullRequest
4 голосов
/ 22 ноября 2008

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

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

Ответы [ 5 ]

8 голосов
/ 23 ноября 2008

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

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

preg_replace('/&(?![a-z#]+;)/i','&',$txt);
7 голосов
/ 22 ноября 2008

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

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

4 голосов
/ 22 ноября 2008

Росс привел меня к хорошему ответу. Вот код, который, кажется, работает довольно хорошо. До сих пор. :-) Цель, опять же, конвертировать 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');
2 голосов
/ 23 ноября 2008

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

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

&                      # 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 ';'
1 голос
/ 26 марта 2010

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

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

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


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

  return $string;
}

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

...