为什么PHP';s preg_将希伯来文字母拆分为“נ”;在UTF-8中,在“上拆分时\s”;?

为什么PHP';s preg_将希伯来文字母拆分为“נ”;在UTF-8中,在“上拆分时\s”;?,php,utf-8,whitespace,pcre,hebrew,Php,Utf 8,Whitespace,Pcre,Hebrew,这不起作用,它会变成胡言乱语: $foo = 'נ'; $bar = mb_convert_encoding($foo, 'UTF-8', mb_detect_encoding($foo)); print_r(preg_split('/\s/', $bar)); 数组([0]=>� [1] =>) 但这是可行的: $foo = 'נ'; $bar = mb_convert_encoding($foo, 'ISO-8859-8', mb_detect_encoding($foo)); $baz

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

$foo = 'נ';
$bar = mb_convert_encoding($foo, 'UTF-8', mb_detect_encoding($foo));
print_r(preg_split('/\s/', $bar));
数组([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'));
נ


问题只出在字母“
נ
”上。它适用于所有其他希伯来文字母。有解决方案吗?

处理UTF-8数据时,请始终在模式中使用:

/\s/u
因为否则该模式不会被解释为UTF-8

与本例类似,字符
נ
(U+05E0)在UTF-8中用0xD7A0编码。和
\s
表示任何空白字符(根据):

\s
字符为HT(9)、LF(10)、FF(12)、CR(13)和空格(32)

在添加UTF-8支持时,他们还添加了一个名为PCRE\U UCP的特殊选项,使其具有
\b
\d
\s
\w
不仅匹配US-ASCII字符,还通过其Unicode属性匹配其他Unicode字符:

默认情况下,在UTF-8模式下,值大于128的字符从不匹配
\d
\s
\w
,并且始终匹配
\d
\s
\w
。[…]但是,如果使用Unicode属性支持编译PCRE,并且设置了PCRE_UCP选项,则会更改行为,以便使用Unicode属性确定字符类型,如下所示:

  • \d
    \p{Nd}
    匹配的任何字符(十进制数字)
  • \s
    匹配的任何字符,加上HT、LF、FF、CR
  • \w
    \p{L}
    \p{N}
    匹配的任何字符,加下划线
非中断空间U+00A0具有分隔符(
\p{Z}
)的属性

因此,尽管您的模式未处于UTF-8模式,但似乎
\s
与UTF-8码字0xD7A0中的0xA0匹配,在该位置拆分字符串并返回一个与
数组(“\xD7”,”)
等效的数组


这显然是一个错误,因为模式不是UTF-8模式,但0xA0大于0x80(此外,0xA0将被编码为0xC2A0)。可能与此相关。

@happytoad:我已经为这种特定行为添加了一些可能的解释。对Unicode字符和Unicode属性之间的关系感兴趣的人,包括
\s
\v
(垂直空间)和
\h
(水平空间)等内容应该抓取我的两个基本实用程序,然后。包括说明和示例。还有第三个相关的程序,你可能也喜欢。