PHP preg_match 非贪婪匹配的神秘bug
很偶然的发现php的正则表达中有一个神秘的bug, 结果是执行一个简单的表达式匹配耗时超过30秒, 而且似乎只在Windows平台上出现, 同样的表达式, 同样的输入数据, 在Linux上检测不到延迟, 即我们精确到毫秒的时候是检测不出来的, 也就是说正常情况下这个语句应该在1毫秒以内完成, 但是在Windows上面却要耗费30秒.
要重现这个bug, 必须是Windows平台, 而且configure command中没有下面的配置
--with-pcre-regex=/usr/local
我不确定究竟是操作系统的原因还是with-pcre-regex的原因, 因为我没有在Windows下面以这个选项编译PHP.
第二个是正则表达式必须是如下格式
'/([\s\S]*?)abc/'
这里abc就是普通的字符串, 数目大于等于3个以上, 即下面的两个没有延迟
'/([\s\S]*?)a/' '/([\s\S]*?)ab/'
只要等于3个字符或者以上, 结果就是需要大概30s的时间完成. 多次实验之后发现, 这个时间和输入文本串的长度成线性关系, 较短的文本耗时1s左右, 随着长度的增长, 耗时同步增长, 无论正则表达式是否在文本串种找到匹配, 都是如此.
这是一个非贪婪匹配, 意思是匹配任意字符, 直到碰到第一个"abc", 已匹配的部分不会包含"abc".
但是目前搜索不到任何有关的信息, 原因有两点: 很少人用wamp开发, 即使开发, 未必会用到类似上面的表达式, 二是即使用wamp, 也不会用internal pcre, 而external pcre没有这个问题.