4

在版本 5.3.4 - 5.5.0beta1 中,是否\w\pL等价?

 <?php
preg_match_all('#\w#u','سیب',$f);
var_dump($f);

preg_match_all('#\pL#u','سیب',$f);
var_dump($f);

array(1) {
  [0]=>
  array(3) {
    [0]=>
    string(2) "س"
    [1]=>
    string(2) "ی"
    [2]=>
    string(2) "ب"
  }
}
array(1) {
  [0]=>
  array(3) {
    [0]=>
    string(2) "س"
    [1]=>
    string(2) "ی"
    [2]=>
    string(2) "ب"
  }
}

在 Online PHP shell 中尝试上面的代码片段

4

1 回答 1

8

看起来当您u在 PCRE 正则表达式中使用修饰符时,PHP 除了设置PCRE_UCPflag 之外,还设置了PCRE_UTF8flag,导致将 Unicode 属性引入到\w其他 POSIX 字符类中,而不仅仅是默认的 ASCII 字符。从PCRE 的手册页

PCRE_UCP

此选项更改 PCRE 处理 \B、\b、\D、\d、\S、\s、\W、\w 和一些 POSIX 字符类的方式。默认情况下,仅识别 ASCII 字符,但如果设置了 PCRE_UCP,则使用 Unicode 属性来对字符进行分类。

然后在 PHP 源代码(第 366-372 行)中确认了这一点,我们在其中看到:

        case 'u':   coptions |= PCRE_UTF8;
/* In  PCRE,  by  default, \d, \D, \s, \S, \w, and \W recognize only ASCII
   characters, even in UTF-8 mode. However, this can be changed by setting
   the PCRE_UCP option. */
#ifdef PCRE_UCP
                    coptions |= PCRE_UCP;
#endif

因此,从我上面链接的同一个手册页中,您会看到PCRE_UCP设置时,字符类变为:

\d 任何 \p{Nd} 匹配的字符(十进制数字)

\s 任何 \p{Z} 匹配的字符,加上 HT、LF、FF、CR

\w 任何 \p{L} 或 \p{N} 匹配的字符,加上下划线

于 2013-03-29T03:30:50.613 回答