PCRE模式
PHP 手册

与 perl 的不同之处

这里讨论的不同之处是与 perl 5.005相比的。

  1. 尽管可以使用字符类编译 pcre 进行替代,但仍然默认使用 c 库函数 isspace() 判定一个字符是否是空白字符。通常 isspace() 匹配空格、换页符、换行符、 回车符、水平制表符和垂直制表符。 Perl5 不再将垂直制表符包括到空白字符集中。 \v 这个转义实际上在很长时间都没有得到 perl 文档的承认。然而,这个字符自身 被认为是一个空白字符至少是在 5.002 以上。 在 5.004 和 5.005 它不和 \s 匹配。
  2. PCRE 不允许前瞻断言的量词修饰,perl 允许这样做,但是这并不是你想象的那样。 例如,(?!a){3}并不意味着接下来 3 个字符不是 a,而是断言下一个字符不是 a 并进行了 3 次断言.
  3. 捕获子组发生在消极前瞻断言中时被计算在内,但是在偏移向量中并没有设置它们的条目。 Perl 从断言失败之前匹配得到的这些模式匹配结果中设置了它的数值变量(因此是成功的), 但这也仅在消极前瞻断言只有一个分支的时候。
  4. 尽管目标字符串中支持二进制 0 字符,但是它们在模式字符串中是不允许的,因为它们是通过普通的 c 字符串传递的,而 c 字符串是以 0 字符结束的。转义序列"\x00"可以在模式中表示二进制 0 字符。
  5. 不支持下面的 perl 转义序列:\l、\u、 \L、 \U。 实际上这些都是通过 perl 一般的字符串处理来实现 的,而不是模式匹配引擎的一部分。
  6. 不支持 perl 的 \G 断言,因为它与单模式匹配没有关系。
  7. 很显然,PCRE不支持(?{code}) 和 (??{code})的结构,但是它支持递归模式。
  8. 在 perl 5.005_2 中档设置为捕获字符串的模式中有部分重复的时候会有一些古怪的现象发生, 比如: /^(a(b)?)+$/ 捕获 aba 的时候, $2 会被设置为 b,然而,如果把模式修改为/^(aa(bb)?)+$/, 用aabbaa去匹配,$2讲不会得到匹配结果。 如果将模式修改为 /^(aa(b(b))?)+$/, $2 和 $3 又都能 得到匹配结果。在 perl 5.004 中 $2 在这几种情况下都能够得到匹配结果,并且 pcre 也是这样。如果 未来 perl 修改为一致那就不同了。pcre 可能接下来会修改.
  9. 还有一个没有解决的差异是 perl 5.005_02中,模式 /^(a)?(?(1)a|b)+$/ 会匹配字符串 "a", 而 pcre 中不会,然而,perl 和 pcre 中 /^(a)?a/ 匹配 "a" 都会得到相同的结果,$1 都未被设置。
  10. PCRE 提供了一些对 perl 正则表达式的扩展:

    1. 虽然后瞻断言要求必须匹配固定长度的字符串,然而后瞻断言的每个可选分支 还是可以使用不同长度的字符串的,而perl 5.005 中要求它们必须拥有同样 的长度。
    2. 如果设置了 PCRE_DOLLAR_ENDONLY 并且没有设置 PCRE_MULTILINE, 元字符 $ 仅仅匹配字符串的末尾(而不是某个换行符之前)。
    3. 如果设置了 PCRE_EXTRA, 反斜线后紧跟一个没有特殊含义的字符讲会导致错误。
    4. 如果设置了 PCRE_UNGREEDY, 贪婪量词修饰被逆转,也就是说,默认它们都是非贪婪的了,但如果紧跟一个问号它们就会变成 贪婪的。(译注:既完全将贪婪模式逆转。)


PCRE模式
PHP 手册