preg_match_all suddenly ceased to find occurrences in text
我有一些代码可以通过使用preg_match_all在电子邮件正文中查找发生的事件。像这样:
1 2 3 4 | $sHrefPattern ="<(a|area)\s*.*(unsubscribe_url\s*=\s*?)(["\']??)([^">]*?)"; if (preg_match_all("/$sHrefPattern/siU", $sHtmlBody, $aMatches, PREG_SET_ORDER)) { // do smth ... } |
和类似内容(可以包含俄语文本出现):
1 2 3 4 5 6 7 8 | ... <td align="left" colspan="3" height="22" valign="center"> Unsubscribe | Advertisement in emails </td> ... |
号
很长一段时间以来,这个代码工作得很好。但有一天,这个代码停止正常工作。我认为它与一些程序包安装相关,但我不知道安装了哪个程序包。此代码所在的服务器在我们的团队中具有共享访问权限。有什么想法吗?
1 2 | uname -a Linux ourhost 2.6.32-042stab076.8 #1 SMP Tue May 14 20:38:14 MSK 2013 i686 i686 i386 GNU/Linux |
我认为你睡着的时候,坏人已经编辑了你的模式,幸运的是,我建议你测试一下这个模式来取代旧模式:
1 2 3 4 | $sHrefPattern ="rea)?\b(?>[^u]++|u++(?!nsubscribe_url\b))+" ."unsubscribe_url\s*+=\s*+["']?+\K[^"'\s]++"; preg_match_all("/$sHrefPattern/iu", $sHtmlBody, $aMatches, PREG_SET_ORDER); print_r($aMatches); |
它是为快速失败而优化的,也要注意新的标志,现在结果是整个模式(不需要捕获组),(即0组)。
检查所涉及的字符集。我不知道最近在这方面对PHP所做的任何更改,但是您的regexp是否也包含俄语?您使用的是8位西里尔字符集还是UTF-8?它是由PHP显式设置还是检测?也许您的代码只是忽略了编码的问题,并且在某个地方更改了一些默认值。我建议把它当作新代码来调试。找到一个失败的regexp,找到一个它失败的小输入,并尝试确定它的编码。
regexps可以使用