当检查某些电子邮件地址时,正则表达式“陈旧”

时间:2018-11-14 14:46:35

标签: c# regex

我们有一个系统,可以从外部数据发送交易电子邮件。由于我们无法确定该数据的有效性,因此我们使用正则表达式进行相当基本的语法检查,如果失败,则记录失败并进行检查。

正则表达式为:

^([A-Za-z0-9]([_\.\-]?[a-zA-Z0-9]+)*)([_\.\-]?)@([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$

直到昨天,这一直没有任何实际问题。它已经处理了一些特殊情况的电子邮件,但是对于大多数人来说,它是合算的。但是,该应用程序开始停止运行,结果表明,当检查某些电子邮件地址时,正则表达式将永远不会返回,代码如下;

var regex = new Regex(regexPattern, RegexOptions.IgnoreCase);
return regex.IsMatch(email);

为了解决这个问题,我在regex中设置了超时;

var regex = new Regex(regexPattern, RegexOptions.IgnoreCase, TimeSpan.FromSeconds(1));
return regex.IsMatch(email);

但是,问题是为什么它只会停顿下来。电子邮件的示例是;

first.laste@domain.co.uk(M
name@domain.com(H)

我们每天发送的记录超过100万条,到目前为止,有5条记录失败了。

2 个答案:

答案 0 :(得分:3)

您的模式导致catastrophic backtracking输入不匹配,因为您的特殊字符模式([_.-])在量化组内是可选的,前面的模式与后面的可选特殊模式相同字符模式。

必须使用特殊的字符模式。

这是一个固定的模式(具有更多修复程序并删除了捕获组,如果需要,可以放回捕获括号(如果稍后在代码中的任何位置分析匹配项)):

^[A-Za-z0-9]+(?:[_.-][a-zA-Z0-9]+)*[_.-]?@[A-Za-z0-9]+(?:[.-][a-zA-Z0-9]+)*\.[A-Za-z]{2,}$

请参见regex demo

详细信息

  • ^-字符串的开头
  • [A-Za-z0-9]+-1个以上的字母/数字
  • (?:[_.-][a-zA-Z0-9]+)*-_.-的0+次重复,后跟1+个字母/数字
  • [_.-]?-可选的_.-
  • @-一个@字符
  • [A-Za-z0-9]+-1个以上的字母/数字
  • (?:[_.-][a-zA-Z0-9]+)*-_.-的0+次重复,后跟1+个字母/数字
  • \.-一个.字符
  • [A-Za-z]{2,}-2个或更多字母
  • $-字符串的结尾。

答案 1 :(得分:0)

模式的这一部分:

([A-Za-z0-9]+)(([.-]?[a-zA-Z0-9]+))

可能会导致灾难性的回溯。由于可选部分([A-Za-z0-9]+),这两个子模式(([.-]?[a-zA-Z0-9]+)) [.-]?并不互斥。

另请参阅: