4

这是目标:用 & 替换所有独立的 & 符号。但不能替换那些已经是 HTML 实体(例如  )的一部分。

我想我需要一个 PHP 的正则表达式(最好是 preg_ 函数),它只匹配独立的 & 符号。我只是不知道如何用 preg_replace 做到这一点。

4

5 回答 5

8

PHPhtmlentities()对此有double_encode争论。

如果你想在正则表达式中做类似的事情,那么否定断言会很有用:

preg_replace('/&(?!(?:[[:alpha:]][[:alnum:]]*|#(?:[[:digit:]]+|[Xx][[:xdigit:]]+));)/', '&', $txt);
于 2008-11-22T23:34:16.987 回答
7

你总是可以先跑html_entity_decode再跑htmlentities?除非你只想做 & 符号(即使那样你也可以使用字符集参数)。

比正则表达式更容易和更快。

于 2008-11-21T23:52:18.510 回答
4

罗斯让我得到了一个很好的答案。这是似乎运行良好的代码。至今。:-) 同样,目标是将 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');
于 2008-11-22T00:32:57.493 回答
2

其他的都是很好的建议,可能是更好的方法。但我想我会尝试按要求回答这个问题——如果只是为了提供一个正则表达式示例。

以下是某些发动机允许的特殊分解形式。当然,奇怪的是允许注释正则表达式的引擎允许其他简化表达式 - 但不是通用的。我将在评论中将这些简化的表达式放在括号中。

&                      # 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 ';'
于 2008-11-22T23:15:01.207 回答
1

我有同样的问题,最初是使用:

$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;
}

它并不完美,但足以满足我的需求。

于 2010-03-26T19:51:27.217 回答