我遇到了一个意想不到的角色替换问题。字符代码为8217,’。
我试过用斜杠来逃避这个角色,但没什么区别。
php > $a = preg_replace('/([.,\'"’:?!])<\/a>/', '</a>\1', 'letter">Evolution’</a> </li>');
php > echo($a);
// => letter">Evolution/a> </li>
// Just to show that it works if the character is different
php > $a = preg_replace('/([.,\'"’:?!])<\/a>/', '</a>\1', 'letter">Evolution"</a> </li>');
php > echo($a);
letter">Evolution</a>" </li>我希望它能输出
letter">Evolution</a>’ </li>
而不是
letter">Evolution/a> </li>
发布于 2019-08-30 15:42:30
默认情况下,pcre (pcre引擎)认为您的模式是一系列单字节编码字符。因此,在编写[’]时,您将获得一个字符类,其中包含编码正确单引号(U+2019)的三个字节,即:\xE2、\x80、\x99。
换句话说,在这种默认模式下写"/[’]/"就像写"/[\xE2\x80\x99]/"、"/[\x80\xE2\x99]/"或"/[\x99\xE2\x80]/"等等,regex引擎没有看到表示字符’的字节序列,而只看到三个字节。
这就是为什么您获得了一个奇怪的结果,因为[.,\'"’:?!]只匹配’的最后一个字节,所以是\x99。
要解决这个问题,您必须强制regex引擎以UTF-8编码字符串的形式读取模式。你可以用这样的一种方法来做:
preg_replace('~(*UTF)([.,\'"’:?!])</a>~', '</a>\1', 'letter">Evolution’</a> </li>');preg_replace('~([.,\'"’:?!])</a>~u', '</a>\1', 'letter">Evolution’</a> </li>');这一次,三个字节的\xE2\x80\x99被视为字符’的原子序列。
注意:(*UTF)只用于读取模式,但u修饰符做了更多的事情:它将速记字符类(如\s、\w、\d)扩展到unicode字符,并检查主题字符串是否编码了utf-8。
发布于 2019-08-30 15:43:59
只需将unicode标志添加到regex:
$a = preg_replace('/([.,\'"’:?!])<\/a>/u', '</a>\1', 'letter">Evolution’</a> </li>');
# here ___^
echo($a); https://stackoverflow.com/questions/57729025
复制相似问题