为什么要遵循js码字:
"آرد@".replace(/(?=.)/g,'!'); // returns: ""!آ!ر!د""
但它的 php 等效返回'!�!�!�!�!�!�'
?
preg_replace('/(?=.)/u', '!', 'آرد'); //returns '!�!�!�!�!�!�'
这仅适用于 4.3.5 - 5.0.5、5.1.1 - 5.1.6 版本。
见:http: //3v4l.org/jrV0W
为什么要遵循js码字:
"آرد@".replace(/(?=.)/g,'!'); // returns: ""!آ!ر!د""
但它的 php 等效返回'!�!�!�!�!�!�'
?
preg_replace('/(?=.)/u', '!', 'آرد'); //returns '!�!�!�!�!�!�'
这仅适用于 4.3.5 - 5.0.5、5.1.1 - 5.1.6 版本。
见:http: //3v4l.org/jrV0W
如果您只是添加/u
修饰符,则该模式应该被视为utf-8
. 第二个示例有效,因为:
\p{L}
可以翻译为:“是来自任何语言的任何类型的字母”。\pL
。速记仅适用于单字母 Unicode 属性。更新:为什么preg_replace('/(?=.)/u', '!', 'آرد'); //returns '!�!�!�!�!�!�'??
正如@MarkFox 所说,原因是因为在它的上下文中preg_replace()
假设每个字符一个字节,而您“RegExing”的字符是多字节的。这就是为什么您的替换输出具有您期望的双倍匹配,它匹配每个字符的每个字节(我推断为两个字节) -
无论您对文档编码做什么,都需要使用Unicode 字符属性才能使其正常工作。
那个奇怪的符号呢?
当您看到“内部带有问号的奇怪方形符号”(也称为替换字符)时,通常表明您有一个 80-FF (128-255) 范围内的字节并且系统正在尝试渲染它在UTF-8
.
整个字节范围对于 中的单字节字符无效UTF-8
,但在西方编码中都很常见,例如ISO-8859-1
.
现在测试了一些字符串后,我认为 PREG 引擎中存在错误。前三行输出符合预期,但第四行出现故障。
<?php
echo preg_replace('/./' , '#', 'آرد') . PHP_EOL; //✓
echo preg_replace('/./u' , '#', 'آرد') . PHP_EOL; //✓
echo preg_replace('/(?=.)/' , '#', 'آرد') . PHP_EOL; //✓
echo preg_replace('/(?=.)/u' , '#', 'آرد') . PHP_EOL; //✗
echo preg_replace('/(?=\pL)/' , '#', 'آرد') . PHP_EOL; //?
echo preg_replace('/(?=\pL)/u', '#', 'آرد') . PHP_EOL; //?
输出:
######
###
#�#�#�#�#�#�
#�#�#�#�#�#�
#آ#ر#د
#آ#ر#د