PHP 5.6 正则表达式意外行为

PHP 5.6 regex unexpected behaviour

我在 PHP 5.6 中遇到了一个奇怪的行为(没有用其他版本测试过)

var_dump(preg_match('#\b(39||90)\b#', '42')); // int(1)
var_dump(preg_match('#\b(39||90)\b#', '')); // int(0)

https://regex101.com 表示模式 \b(39||90)\b 无效,但 PHP preg_match 不会 return FALSE,因为如果模式无效,它应该如此。

如您所见,42 生成匹配项,空字符串生成不匹配项。我希望反过来,因为 || 应该代表空字符串。

这里发生了什么?

这个正则表达式:

\b(39||90)\b

将return匹配成功,如果任何交替匹配。它们是:

  1. 完整单词39
  2. 完整单词90
  3. 输入中任意位置的单词边界(因为空||

但是在空字符串中没有单词边界。词边界 \b 在词 \w 和非词 \W 之间断言为真。

例如查看这些结果:

// no word character hence false
var_dump(preg_match('#\b(39||90)\b#', '#@'));
int(0)

# a word char hence true
php > var_dump(preg_match('#\b(39||90)\b#', 'a'));
int(1)

// no word character hence false
php > var_dump(preg_match('#\b(39||90)\b#', "\t\n"));
int(0)