首页 > 解决方案 > 在搜索大量字符串时,如何加快电子邮件查找正则表达式的速度?

问题描述

我有一个巨大的字符串。它看起来像这样:

hej34g934gj93gh398gie foo@bar.com e34y9u394y3h4jhhrjg bar@foo.com hge98gej9rg938h9g34gug

除了它更长(1,000,000+ 个字符)。

我的目标是找到此字符串中的所有电子邮件地址。

我尝试了许多解决方案,包括这个:

#matches foo@bar.com and bar@foo.com
re.findall(r'[\w\.-]{1,100}@[\w\.-]{1,100}', line)

尽管上面的代码在技术上是可行的,但执行起来需要大量的时间。我不确定它是否算作灾难性的回溯,或者它是否真的效率低下,但无论如何,它对我的​​用例来说还不够好。

我怀疑有更好的方法来做到这一点。例如,如果我使用此正则表达式仅搜索电子邮件地址的后半部分:

#matches @bar.com and @foo.com
re.findall(r'@[\w-]{1,256}[\.]{1}[a-z.]{1,64}', line)

它只需几毫秒即可执行。

我对正则表达式还不够熟悉,无法编写其余部分,但我认为有某种方法可以先找到 @xx 部分,然后再检查第一部分?如果是这样,那么我猜这会快得多。

标签: pythonregex

解决方案


不要在整个字符串上使用正则表达式。正则表达式很慢。避免它们是提高整体性能的最佳选择。

我的第一种方法如下所示:

  • 在空格上拆分字符串。
  • 将结果过滤到包含@.
  • 创建一个预编译的正则表达式。
  • 仅对其余部分使用正则表达式以消除误报。

另一个想法:

  • 在一个循环中......
  • 用于.index("@")查找下一个候选人的位置
  • 例如向左扩展 100 个字符,向右扩展 50 个字符以覆盖名称和域
  • 根据您找到的最后一个电子邮件地址调整范围,以免重叠
  • 使用正则表达式检查范围,如果匹配,yield则匹配

推荐阅读