我有一个查找电子邮件地址的正则表达式(这是从我找不到的另一个SO帖子中获取的,并且已经在各种电子邮件配置上进行了测试...更改这不是我的问题...但要明白这是否是根本原因):
/[a-z0-9_\-\+]+@[a-z0-9\-]+\.([a-z]{2,3})(?:\.[a-z]{2})?/i
我在PHP中使用preg_match_all()。
这适用于99.99%的文件我正在查看并需要大约5毫秒,但有时需要几分钟。这些文件大于300k左右的平均网页,但更大的文件通常处理得很好。我能在文件内容中找到的唯一突出的是数千个连续的“随机”字母数字字符串,如下所示:
wEPDwUKMTk0ODI3Nzk5MQ9kFgICAw9kFgYCAQ8WAh4H...
以下是导致问题的两个页面。查看源代码以查看长字符串。
有关导致此问题的任何想法?
- 最终解决方案 -
我测试了答案中建议的各种正则表达式。 @FailedDev的回答有助于将处理时间从几分钟缩短到几秒钟。 @hakre的答案解决了问题并将处理时间缩短到几百毫秒。以下是我使用的最终正则表达式。这是@hakre的第二个建议。
/[a-z0-9_\-\+]{1,256}+@[a-z0-9\-]{1,256}+\.([a-z]{2,3})(?:\.[a-z]{2})?/i
答案 0 :(得分:8)
您已经知道正则表达式导致大文件出现问题。那么也许你可以让它变得更聪明一点?
例如,您使用+
来匹配一个或多个字符。假设你有一串10 000个字符。正则表达式必须看10000个组合才能找到最大的匹配。然后你将它与类似的结合起来。假设你有一个包含20 000个字符和两个+
组的字符串。他们怎么能在文件中匹配。可能是10 000 x 10 000种可能性。依此类推。
如果您可以限制字符数(这看起来有点像您正在寻找电子邮件模式),可能会将电子邮件地址域名限制为256,将地址本身限制为256个字符。那么这将是“仅”测试的256 x 256种可能性:
/[a-z0-9_\-\+]{1,256}@[a-z0-9\-]{1,256}\.([a-z]{2,3})(?:\.[a-z]{2})?/i
这可能已经快得多了。然后使这些量词占有率将减少PCRE的回溯:
/[a-z0-9_\-\+]{1,256}+@[a-z0-9\-]{1,256}+\.([a-z]{2,3})(?:\.[a-z]{2})?/i
哪个应该再次加速。
答案 1 :(得分:6)
我最好的猜测是尝试使用积极的量词:
[a-z0-9_\-\+]+
到
[a-z0-9_\-\+]++
这应该会使正则表达式失败,因此可以在这些情况下提高性能。
编辑:
也许 原子分组也可以提供帮助:
/(?>[a-z0-9_\-+]++)@(?>[a-z0-9\-]++\.)(?>[a-z]{2,3})(?:\.[a-z]{2})?/
你应该先选择第一选项。通过使用选项2看看是否存在任何差异将会很有趣。