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

时间:2012-10-18 12:26:22

标签: c# asp.net regex asp.net-mvc-2 email-validation

我目前正在使用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})$

这是一个验证“有效”电子邮件地址格式的电子邮件正则表达式。我的代码如下:

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.");

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

iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii

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

host.@.host..com

1 个答案:

答案 0 :(得分: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的每个可能的排列(这是很多排列)。

In general, validating email addresses with a regular expression is hard.