5

我得到了一个很好的电子邮件验证正则表达式: 电子邮件正则表达式

    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 App 中测试过。在标准的 .Net 4.5 应用程序上。

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

非常感谢,乔恩

4

3 回答 3

15

它挂起的解释:灾难性回溯

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

(\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 建议)
  • 尝试向它发送电子邮件——即使是看似有效的地址也可能是伪造的,所以无论如何你都必须这样做。

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

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);
于 2012-10-26T13:30:13.853 回答
4

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

您可以使用MailAddress类来验证它

try 
{
    address = new MailAddress(address).Address;
   //address is valid
} 
catch(FormatException)
{
    //address is invalid
}
于 2012-10-26T13:22:48.617 回答
1

猜想是因为正则表达式中的 [-.\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 中应该可用,但不确定

于 2012-10-26T13:25:14.400 回答