任何人都可以告诉我为什么这个C#电子邮件验证正则表达式(正则表达式)挂起?

时间:2012-10-26 13:19:37

标签: c# regex

我收到了一封好的电子邮件vaidation正则表达式: Email regular expression

    public static void Main(string[] args)
    {
        string value = @"cvcvcvcvvcvvcvcvcvcvcvvcvcvcvcvcvvccvcvcvc";
        var regex = new Regex(
            @"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$",
            RegexOptions.Compiled);
        var x = regex.Match(value); // Hangs here !?!
        return;
    }

它适用于大多数情况,但上面的代码挂起,燃烧100%CPU ...我已经在W8 metro应用程序中测试过。以及标准的.Net 4.5应用程序。

有谁可以告诉我为什么会发生这种情况,如果有一个好的电子邮件验证REGEX没有挂起,或者是否有办法解决这个问题?

非常感谢, 乔恩

3 个答案:

答案 0 :(得分:14)

解释原因:Catastrophic backtracking

让我们简化正则表达式的关键部分:

(\w*[0-9a-zA-Z])*@

你有

  • 可选部分\w*,可以匹配与以下部分[0-9a-zA-Z]相同的字符,因此两者合并翻译为\w+
  • 嵌套量词:(\w+)*

这意味着,在给定s = "cvcvcvcvvcvvcvcvcvcvcvvcvcvcvcvcvvccvcvcvc"的情况下,正则表达式的这一部分需要检查s的所有可能排列(2**(len(s)-1)处的数字),然后才能确定不匹配找不到@

由于您无法使用任何正则表达式验证电子邮件地址(规范中存在太多极端情况),通常最好

  • 进行最小的正则表达式检查(^.*@.*$
  • 使用解析器检查有效性(如@ Fake.It.Til.U.Make.It建议)
  • 尝试向其发送电子邮件 - 即使看似有效的地址可能是虚假的,所以无论如何你都必须这样做。

为了完整起见,您可以在atomic groups的帮助下避免回溯问题:

var regex = new Regex(
    @"^([0-9a-zA-Z](?>[-.\w]*[0-9a-zA-Z])*@(?>[0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$",
    RegexOptions.Compiled);

答案 1 :(得分:4)

永远不要使用regex验证电子邮件..

您可以使用MailAddress类来验证它

try 
{
    address = new MailAddress(address).Address;
   //address is valid
} 
catch(FormatException)
{
    //address is invalid
}

答案 2 :(得分:0)

猜测是因为正则表达式中的[ - 。\ w],尝试使用它:

^[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)*@(?:(\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$

此外,在.net 4.5中,EmailAttribute应该可用,但不确定