为什么w在Mac OS X PHP环境中匹配非英文字符


Why does w match Non-English characters in Mac OS X PHP environment?

我发现"''w"可以在我的Mac OS X PHP环境中匹配中文字符。但同样的代码在Linux上不起作用。

php -r "echo preg_match('/^'w+$/','人1234', '$m).chr(10); var_dump('$m);"

Mac OS X 11.11.3,带有PHP 5.6.8(cli(、PHP 5.4.45(cli(result

1
array(1) {
  [0] =>
  string(7) "人1234"
}

Cent OS 6,带有PHP 5.6.8(cli(、PHP 5.2.17p1(cli(result

0
array(0) {
}

PHP手册说

字母和数字的定义由PCRE的字符表控制,如果进行特定于区域设置的匹配,则可能会有所不同。例如,在"fr"(法语(区域设置中,一些大于128的字符代码用于重音字母,这些字符代码由''w匹配。">

我猜有什么链接到PCRE库。有人能解释一下原因吗?

是的,这一切都是关于PCRE如何与PHP:一起编译的

pcre *pcre_compile(const char *pattern,
      int options,
      const char **errptr,
      int *erroffset,
      const unsigned char *tableptr); 

在这个负责将RegExes编译成其内部形式的函数中,options参数是一个位列表,包括允许'w'd和其他令牌使用Unicode属性的PCRE_UCP(UCP=Unicode字符属性(,并且似乎在Mac OS X机器上的PHP PCRE是在打开此标志的情况下编译的。

还有一个特殊的修饰符(*UCP),您可以随时使用它,即使您的PCRE没有使用PCRE_UCP标志集进行编译,您也可以在运行时启用这样的选项。

例如,/(*UCP)'w+/也匹配unicode字符。(在线查看(

来自PCRE网站:

PCRE处理无案例匹配,并确定字符是否是字母、数字或其他什么,通过参考一组表格,按字符代码点编制索引。

当在UTF-8模式下或在16或32位库中运行时仅适用于代码点小于256的字符。默认情况下,较高值的代码点从不匹配转义符,例如'w或CCD_ 10。

但是,如果PCRE是使用Unicode属性支持构建的,则所有字符可以用''p和''p进行测试,或者在编译模式时可以设置PCRE_UCP选项这会导致'w和朋友使用Unicode属性支持,而不是内置表

不鼓励使用带有Unicode的区域设置。如果你是处理代码点大于128的字符时,应该使用Unicode支持或使用区域设置,但不要尝试混合二