我们有一个系统,可以从外部数据发送交易电子邮件。由于我们无法确定该数据的有效性,因此我们使用正则表达式进行相当基本的语法检查,如果失败,则记录失败并进行检查。
正则表达式为:
^([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条记录失败了。
答案 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]+))
[.-]?
并不互斥。
另请参阅: