C# 为什么Regex IsMatch()挂起
我有一个验证电子邮件地址的表达式:C# 为什么Regex IsMatch()挂起,c#,.net,regex,C#,.net,Regex,我有一个验证电子邮件地址的表达式: string REGEX_EMAIL = @"^\w+([\.\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\¦\}\~]*\w+)*@\w+([\.\-]\w+)*\.\w+([\.\-]\w+)*$"; 如果地址正确,IsMatch()方法将快速显示真实结果。但如果地址字符串很长且错误,则此方法将挂起 如何提高此方法的速度 谢谢。您正在体验 简化正则表达式: Regex regexObj = new Regex(@"^\w+([-.
string REGEX_EMAIL = @"^\w+([\.\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\¦\}\~]*\w+)*@\w+([\.\-]\w+)*\.\w+([\.\-]\w+)*$";
如果地址正确,IsMatch()方法将快速显示真实结果。但如果地址字符串很长且错误,则此方法将挂起
如何提高此方法的速度
谢谢。您正在体验
简化正则表达式:
Regex regexObj = new Regex(@"^\w+([-.!#$%&'*+/=?^`{¦}~]*\w+)*@\w+([.-]\w+)*\.\w+([.-]\w+)*$");
存在潜在问题,例如([.-]\w+*\.
例如,如果缺少
,并且前面有一个很长的字符串,则必须考虑所有可能的组合,以便您的正则表达式能够发现它实际上失败了。您有一些事情正在影响此正则表达式的性能
通过在一些关键位置使用+
而不是*
,您肯定可以提高性能,但这当然会改变正则表达式将匹配和不匹配的内容。因此,我发现的最简单的修复方法实际上包含在上面的灾难性回溯文章中。在这种情况下,您可以使用非回溯子表达式大幅提高性能,而无需以任何重要的方式更改正则表达式的行为
非回溯子表达式如下所示<代码>(?>模式)
因此,请尝试使用以下正则表达式:
^\w+(?>[\.\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\¦\}\~]*\w+)*@\w+([\.\-]\w+)*\.\w+([\.\-]\w+)*$
关于一个稍微相关的话题,我检查有效电子邮件地址的理念有点不同。首先,正如您所发现的,像这样的长正则表达式可能存在性能问题 第二,即将到来的电子邮件地址国际化承诺使这一切变得更加复杂 最后,任何基于正则表达式的电子邮件验证的主要目的都是捕捉拼写错误和公然试图在不输入真实电子邮件地址的情况下通过表单的行为。但要检查电子邮件地址是否真实,需要向该地址发送电子邮件 因此,我的哲学是错误地接受太多。事实上,这是一件非常简单的事情
^.+@.+\..+$
这应该匹配任何可能有效的电子邮件地址,以及一些无效的电子邮件地址。因此,存在一些回溯问题。您可以谨慎地使用独立的子表达式构造来减少这些问题,但仍然会有问题,因为内部表达式不会有那个约束。最好的办法是把主要部分分开 将其更改为此有助于(扩展): 但是,如果您通过放置一些位置正确的断言来重构等价的表达式,然后重新添加独立的子表达式分组,那么实际上可以消除回溯。通过我的regex dubugger运行此命令,可以看出,通过或失败(扩展)只需几个步骤:
^
(?>
\w+
[\.\!\\\\$\%\&'\*\+-\/\=\?\^\\\\\\\\\\\\\\\\\~\w]*
(?
([\.\-]\w+)+
)
$
你能告诉我们你是如何创建Regex
对象的吗?我不喜欢这个Regex的外观。我不是Regex专家,但如果这些嵌套的可变长度量词导致指数运行,我也不会感到惊讶。此外,管道符号是一个断条(
),而不是一条垂直线(
)。你从哪里得到这个正则表达式的?怎么样:([\w-\.]+)@((?:[\w]+)+)\([\w]{2,4})这样,您就不必单独指定所有字符。@p.wilt-我只是想用最小的更改来解决性能问题。如果我建议使用自己的正则表达式进行电子邮件验证,它将是我最新更新中的小正则表达式。
^
(?>
\w+
(
[\.\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\¦\}\~]*
\w+
)*
@
\w+
)
(?>
([\.\-]\w+)*
\.
\w+
([\.\-]\w+)*
)
$
^
(?>
\w+
[\.\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\¦\}\~\w]*
(?<=\w)
@
\w+
)
(?=.*\.\w)
(?>
([\.\-]\w+)+
)
$