这是目标:用 & 替换所有独立的 & 符号。但不能替换那些已经是 HTML 实体(例如 )的一部分。
我想我需要一个 PHP 的正则表达式(最好是 preg_ 函数),它只匹配独立的 & 符号。我只是不知道如何用 preg_replace 做到这一点。
PHPhtmlentities()
对此有double_encode
争论。
如果你想在正则表达式中做类似的事情,那么否定断言会很有用:
preg_replace('/&(?!(?:[[:alpha:]][[:alnum:]]*|#(?:[[:digit:]]+|[Xx][[:xdigit:]]+));)/', '&', $txt);
你总是可以先跑html_entity_decode
再跑htmlentities
?除非你只想做 & 符号(即使那样你也可以使用字符集参数)。
比正则表达式更容易和更快。
罗斯让我得到了一个很好的答案。这是似乎运行良好的代码。至今。:-) 同样,目标是将 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');
其他的都是很好的建议,可能是更好的方法。但我想我会尝试按要求回答这个问题——如果只是为了提供一个正则表达式示例。
以下是某些发动机允许的特殊分解形式。当然,奇怪的是允许注释正则表达式的引擎允许其他简化表达式 - 但不是通用的。我将在评论中将这些简化的表达式放在括号中。
& # 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("/&([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;
}
它并不完美,但足以满足我的需求。