当分裂为"\ s"时,为什么PHP的preg_split在UTF-8中拆分希伯来字母"נ"?

hap*_*oad 2 php whitespace pcre utf-8 hebrew

这不起作用,它变成了胡言乱语:

$foo = '?';
$bar = mb_convert_encoding($foo, 'UTF-8', mb_detect_encoding($foo));
print_r(preg_split('/\s/', $bar));
Run Code Online (Sandbox Code Playgroud)

数组([0] => [1] =>)

但这有效:

$foo = '?';
$bar = mb_convert_encoding($foo, 'ISO-8859-8', mb_detect_encoding($foo));
$baz = preg_split('/\s/', $bar);
echo(mb_convert_encoding($baz[0], 'UTF-8', 'ISO-8859-8'));
Run Code Online (Sandbox Code Playgroud)

נ

问题只在于字母" ?".它与所有其他希伯来字母一起使用.有解决方案吗?

Gum*_*mbo 7

使用UTF-8数据时,请始终在模式中使用u修饰符:

/\s/u
Run Code Online (Sandbox Code Playgroud)

因为否则该模式不会被解释为UTF-8.

与此情况类似,字符?(U + 05E0)使用UTF-8中的0xD7A0进行编码.并\s代表任何空白字符(根据PCRE):

\s字符是HT(9),LF(10),FF(12),CR(13),和空间(32).

当加入UTF-8的支持,他们还增加了一个叫做PCRE_UCP一个特殊的选项有\b,\d,\s,并\w不仅仅是他们的Unicode属性匹配US-ASCII字符,还包括其他Unicode字符:

默认情况下,UTF-8模式下,其值大于128个字符永远不会匹配 \d, \s或者 \w,和总是匹配\D,\S\W.[...]但是,如果使用Unicode属性支持编译PCRE,并且设置了PCRE_UCP选项,则会更改行为,以便使用Unicode属性来确定字符类型,如下所示:

  • \d\p{Nd}匹配的 任何字符(十进制数字)
  • \s\p{Z}匹配的 任何字符,加上HT,LF,FF,CR
  • \w 任何\p{L}\p{N}匹配的字符,加上下划线

并且那个不间断的空间U + 00A0具有separator(\p{Z})的属性.

所以,虽然你的模式是不是在UTF-8模式,似乎\s 匹配0XA0在UTF-8编码字0xD7A0,拆分该位置的字符串,返回一个数组,等效于array("\xD7", "").

这就是明显的错误作为图案是以UTF-8模式,但0XA0 大于0x80的(另外,将0XA0被编码为0xC2A0).该BUG#52971 不使用UTF-8的工作PCRE-元字符可能与此有关.