JS正则表达式冻结了我的浏览器

时间:2015-01-05 15:48:30

标签: javascript regex

所以我写了这个正则表达式来验证电子邮件地址:

(?=^([A-Za-z\xC0-\xFF0-9\!\#\$\%\&\'\*\+\-\/\=\?\^\\_\`\{\|\}\~]\.?){0,63}[A-Za-z\xC0-\xFF0-9\!\#\$\%\&\'\*\+\-\/\=\?\^\\_\`\{\|\}\~]@[A-Za-z\xC0-\xFF0-9]([A-Za-z\xC0-\xFF0-9-]{0,61}[A-Za-z\xC0-\xFF0-9])?(\.[A-Za-z\xC0-\xFF]([A-Za-z\xC0-\xFF0-9-]{0,61}[A-Za-z\xC0-\xFF0-9])?)*$)(?=^.{3,254}$)

我想在js控制台中测试它:

var patt = new RegExp("(?=^([A-Za-z\xC0-\xFF0-9\!\#\$\%\&\'\*\+\-\/\=\?\^\\_\`\{\|\}\~]\.?){0,63}[A-Za-z\xC0-\xFF0-9\!\#\$\%\&\'\*\+\-\/\=\?\^\\_\`\{\|\}\~]@[A-Za-z\xC0-\xFF0-9]([A-Za-z\xC0-\xFF0-9-]{0,61}[A-Za-z\xC0-\xFF0-9])?(\.[A-Za-z\xC0-\xFF]([A-Za-z\xC0-\xFF0-9-]{0,61}[A-Za-z\xC0-\xFF0-9])?)*$)(?=^.{3,254}$)")

patt.test("jake@domain.domain.domain.domain.domai.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domain.domai")

这冻结了我的标签。较短的地址似乎工作正常。

在C#和在线正则表达式工具(例如regex101.com)中测试没有任何问题。 这是怎么回事? JavaScript Regex引擎有问题,还是只是我的Regex?

(我知道这可能不是一个完美的电子邮件验证,但这个问题是为什么它不起作用)

2 个答案:

答案 0 :(得分:1)

使用RegExp文字而不是RegExp构造函数:

/(?=^(?:[A-Za-z0-9_\xC0-\xFF!#$%&'*+\/=?^`{|}~\\-]\.?){0,63}[A-Za-z0-9_\xC0-\xFF!#$%&'*+\/=?^`{|}~\\-]@[A-Za-z0-9\xC0-\xFF](?:[A-Za-z0-9\xC0-\xFF-]{0,61}[A-Za-z0-9\xC0-\xFF])?(?:\.[A-Za-z\xC0-\xFF](?:[A-Za-z0-9\xC0-\xFF-]{0,61}[A-Za-z0-9\xC0-\xFF])?)*$)(?=^.{3,254}$)/

我冒昧地删除了字符类中的过多转义(在JavaScript中,只有]\需要转义,^如果不在,则-不需要转义字符类的开始,\如果它位于字符类的末尾则不需要转义)并使所有捕获组不捕获(因为您不关心捕获的内容)。

使用RegExp构造函数时,需要提供字符串。您需要转义\才能在字符串文字中指定它;否则,它将被视为字符串中的转义序列,"(?=^([A-Za-z\xC0-\xFF0-9\!\#\$\%\&\'\*\+\-\/\=\?\^\\_\`\{\|\}\~]\.?){0,63}[A-Za-z\xC0-\xFF0-9\!\#\$\%\&\'\*\+\-\/\=\?\^\\_\`\{\|\}\~]@[A-Za-z\xC0-\xFF0-9]([A-Za-z\xC0-\xFF0-9-]{0,61}[A-Za-z\xC0-\xFF0-9])?(\.[A-Za-z\xC0-\xFF]([A-Za-z\xC0-\xFF0-9-]{0,61}[A-Za-z\xC0-\xFF0-9])?)*$)(?=^.{3,254}$)" >>> "(?=^([A-Za-zÀ-ÿ0-9!#$%&'*+-/=?^\_`{|}~].?){0,63}[A-Za-zÀ-ÿ0-9!#$%&'*+-/=?^\_`{|}~]@[A-Za-zÀ-ÿ0-9]([A-Za-zÀ-ÿ0-9-]{0,61}[A-Za-zÀ-ÿ0-9])?(.[A-Za-zÀ-ÿ]([A-Za-zÀ-ÿ0-9-]{0,61}[A-Za-zÀ-ÿ0-9])?)*$)(?=^.{3,254}$)" 将不会到达RegExp构造函数。

您可以在浏览器的控制台中将字符串复制并粘贴到RegExp构造函数中。在Firefox 34.0上:

+-/

虽然对于大多数部分来说不是问题,但,在字符类中形成一个字符范围,其中包括..(不属于类)。你得到了全点(.[A-Za-zÀ-ÿ]([A-Za-zÀ-ÿ0-9-]{0,61}[A-Za-zÀ-ÿ0-9])?)* 而不是字面点,这就是灾难性回溯的原因:

new RegExp("(?=^(?:[A-Za-z0-9_\xC0-\xFF!#$%&'*+/=?^`{|}~\\\\-]\\.?){0,63}[A-Za-z0-9_\xC0-\xFF!#$%&'*+/=?^`{|}~\\\\-]@[A-Za-z0-9\xC0-\xFF](?:[A-Za-z0-9\xC0-\xFF-]{0,61}[A-Za-z0-9\xC0-\xFF])?(?:\\.[A-Za-z\xC0-\xFF](?:[A-Za-z0-9\xC0-\xFF-]{0,61}[A-Za-z0-9\xC0-\xFF])?)*$)(?=^.{3,254}$)")

基于上面的RegExp文字,使用RegExp构造函数的等效代码是:

\

请注意,与RegExp文字相比,所有{{1}}都加倍了。

但是没有理由使用RegExp构造函数。它只应在需要根据某些输入生成正则表达式时使用。固定正则表达式应指定为RegExp文字。

答案 1 :(得分:0)

  

你可以使用这个。它会在[dot] 2,3之后支持   根据您的域名

var email_filter  = /^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
if (email_filter.test('yourEmail@gmail.com')) {
  alert('Email is valid');
}