7

为什么要遵循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

4

2 回答 2

4

如果您只是添加/u修饰符,则该模式应该被视为utf-8. 第二个示例有效,因为:

  1. 从 PHP 5.1 开始,您可以使用\p{L}可以翻译为:“是来自任何语言的任何类型的字母”。
  2. 除了标准符号之外,\p{L}、Java、Perl、PCRE 和现在的PHP都允许您使用简写\pL。速记仅适用于单字母 Unicode 属性。

更新:为什么preg_replace('/(?=.)/u', '!', 'آرد'); //returns '!�!�!�!�!�!�'??

正如@MarkFox 所说,原因是因为在它的上下文中preg_replace()假设每个字符一个字节,而您“RegExing”的字符是多字节的。这就是为什么您的替换输出具有您期望的双倍匹配,它匹配每个字符的每个字节(我推断为两个字节) -

无论您对文档编码做什么,都需要使用Unicode 字符属性才能使其正常工作。

那个奇怪的符号呢?

当您看到“内部带有问号的奇怪方形符号”(也称为替换字符)时,通常表明您有一个 80-FF (128-255) 范围内的字节并且系统正在尝试渲染它在UTF-8.

整个字节范围对于 中的单字节字符无效UTF-8,但在西方编码中都很常见,例如ISO-8859-1.

于 2013-02-18T08:25:40.740 回答
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; //?

输出:

######
###
#�#�#�#�#�#�
#�#�#�#�#�#�
#آ#ر#د
#آ#ر#د
于 2013-02-18T12:57:37.407 回答