Javascript 字符串regex用户名或电子邮件挂起

Javascript 字符串regex用户名或电子邮件挂起,javascript,jquery,regex,Javascript,Jquery,Regex,验证用户名输入字段时出现问题 正则表达式: var mailformat = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/; var letterNumber = /^[0-9a-zA-Z]*$/; 支票: if (!letterNumber.test($('#login_username').val()) && !mailformat.test($('#login_username').val())){ ...

验证用户名输入字段时出现问题

正则表达式:

var mailformat = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/;
var letterNumber = /^[0-9a-zA-Z]*$/;
支票:

if (!letterNumber.test($('#login_username').val()) 
      && !mailformat.test($('#login_username').val())){
 ...
}
当我想验证以下条目时,浏览器(chrome和ie)将挂起:

012345678901234567890123456789@
有人知道为什么吗

我尝试在一个表达式中使用正则表达式,但得到了相同的结果。
(正则表达式可以,因为它们单独工作)

因为灾难性的回溯正在起作用。正则表达式中的大多数术语

`^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$`
几乎匹配测试字符串的全长

`012345678901234567890123456789@`
然后它必须回溯,因为没有发生完全匹配

例如,
^\w+
匹配012345678901234567890123456789@
^\w+([\.-]?\w+*
也是如此,最终
^\w+([\.-]?\w+*@
匹配整个字符串。
现在在
@
后面还有一些词,即<代码>^\w+([\.-]?\w+*@\w+在正则表达式中,因此它必须回溯并为前面的部分找到合适的匹配项,即再次回溯^\w+([\.-]?\w+*@,回溯过程将继续,直到找到匹配项为止。

您无意中发现了

要修复此问题,您可以使用:

^\w+([.-]\w+)*@\w+([.-]\w+)*(\.\w{2,4})+$
在声明匹配失败之前,正则表达式引擎必须检查应用正则表达式的所有可能方式

使用
\w+([.-]?\w+*
)时,每个数字都可以通过
\w+
([.-]?\w+)*
进行匹配,出现故障时
([.-]?\w+)*
的行为与
(\w+*
相同。这创造了许多州,让我们回到过去

强制执行
[.-]
可以消除这种歧义


在(灾难性)回溯上

正则表达式引擎的工作方式是,它在正则表达式中移动,试图将其每个部分与字符串匹配。每次有选择时,它都会保存状态,以便在路径错误时可以回溯到该状态

要进行说明,请参见
*b
如何匹配
abc

  • *
    量词是贪婪的,因此它将尽可能匹配:它从不匹配开始,然后添加
    a
    ,然后添加
    b
    ,然后添加
    c
    。每次引擎记住它选择添加另一个字符时。然后引擎尝试匹配
    b
    ,但我们位于字符串的末尾,因此失败

  • 没什么大不了的,我们回到我们做的最后一个选择:现在
    *
    只匹配
    ab
    。最后的
    b
    仍然与字符串的结尾
    c
    不匹配

  • 我们再回到前面:
    *
    匹配
    a
    b
    最终可以匹配。找到的总体匹配项:
    ab

在知道正则表达式无法匹配输入之前,引擎必须尝试所有这些替代方法。如果允许一个字符与正则表达式的多个部分匹配,则该数字会增加

在您的例子中,它随着字符串的长度呈指数级增长,以至于需要永远才能返回任何内容:这是灾难性的回溯


Friedl在这个主题上做了很好的说明:

你在哪里定义了
username\u-mail
你能提供一个例子来说明你的问题吗?关于username\u-mail的评论很好,谢谢;我编辑了请求以更正;问题依然存在;阅读下面的答案检查你的答案,事实上mailformat正则表达式本身也不起作用。关于这个主题有多篇文章,例如和。我希望这对您有所帮助。@user2992220有关电子邮件验证的信息,请参阅以前的一篇文章。它有很多不错的选择。谢谢你的正确回答。威尔将应用罗宾建议的解决方案。谢谢你的回答。实际上,从根本上删除“?”并不会改变正则表达式。我正在检查你的答案并阅读参考资料(2^30步确实很多)