有没有办法让这个正则表达式更有效率?

时间:2016-09-10 17:35:09

标签: regex

我试图写一个反弹(NDR)处理程序。

基本上这个正则表达式从一段文本中提取出一个电子邮件地址。

[a-z0-9-._%+=!$~]+@[a-z0-9.-]+\.[a-z]{2,15}

根据regex101.com,某些NDR中包含大量文本并需要大量步骤,具体取决于电子邮件在测试块中的位置。他们是一个更好的正则表达式,可以用来提高在NDR中搜索电子邮件的效率吗?

1 个答案:

答案 0 :(得分:2)

回溯通常会占用你的CPU。解决问题的最简单方法是编写这样的正则表达式,它不仅可以识别您正在寻找的令牌,还可以识别无效的令牌。通过这种方式,您可以消除回溯并使速度更快。

但是,找到这样的标记取决于输入文本,基本上,你需要找到一个正则表达式:

  • 尽可能涵盖“无效”文字
  • 尽可能少地回溯

如果您的NDR是纯文本(通常是这样),那么这样的事情应该是最佳的:

(?:[^@]+\s)

基本上它是一个非捕获组,其中任何不是“@”后跟空格。这意味着,它几乎将所有文本“吃掉”到电子邮件地址,禁止正则表达式引擎回溯到这些匹配的组。

完整正则表达式如下所示:

(?:[^@]+\s)([a-z0-9-._%+=!$~]+@[a-z0-9.-]+\.[a-z]{2,15})

在regex101.com的regex调试器中进行比较,看看它的工作原理有何不同。

修改 更合适的解决方案是检查[^a-z0-9-._%+=!$~]而不是\s。所以最终的版本是:

(?:[^@]+[^a-z0-9-._%+=!$~])([a-z0-9-._%+=!$~]+@[a-z0-9.-]+\.[a-z]{2,15})

<强>旁注: 如果您正在考虑优化这样一个简单的正则表达式查询,那么正则表达式很可能不适合您。抛出一些简单的自定义代码,它比一些可怕的正则表达式更快更容易理解和调试。你试图优化它的次数越多 - 它就会变得越大。