为什么这个电子邮件正则表达式在Mvc上这么慢?

Wil*_*eja 0 c# regex asp.net email-validation asp.net-mvc-2

我目前正在使用Asp.net,c#,Mvc2构建一个使用以下正则表达式的系统:

^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$
Run Code Online (Sandbox Code Playgroud)

这是一个电子邮件正则表达式,用于验证"有效"的电子邮件地址格式.我的代码如下:

if (!Regex.IsMatch(model.Email, @"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$"))
                ModelState.AddModelError("Email", "The field Email is invalid.");
Run Code Online (Sandbox Code Playgroud)

正则表达式可以很好地验证电子邮件,但是如果一个特别长的字符串传递给正则表达式并且它是无效的,它会导致系统继续"工作"而不解析页面.例如,这是我试图传递的数据:

iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
Run Code Online (Sandbox Code Playgroud)

上面的字符串会导致系统基本上锁定.我想知道为什么以及我是否可以使用正则表达式以更简单的方式完成相同的事情.我的目标是不正确形成的电子邮件地址,例如以下内容未通过:

host.@.host..com
Run Code Online (Sandbox Code Playgroud)

Raw*_*ing 6

您有嵌套的重复运算符共享相同的字符,这可能导致灾难性的回溯.

例如: ([-.\w]*[0-9a-zA-Z])*

这表示:匹配0或更多,-._0-9a-zA-Z后跟一次0-9a-zA-Z,一次或多次.

i 落在这两个类中.

因此,当在iiiiiiii...正则表达式上运行时匹配每个可能的排列(several "i"s followed by one "i") several times(这是很多排列).

通常,使用正则表达式验证电子邮件地址很难.

  • 我已经链接的问题(或者更确切地说,它的答案)对此进行了非常好的讨论,但基本上,官方电子邮件规范是_complicated_并且很难用正则表达式正确验证. (2认同)