Javascript 导致此RegExp中无限循环的错误在哪里?

Javascript 导致此RegExp中无限循环的错误在哪里?,javascript,regex,Javascript,Regex,以下是JS中的调用: 'Москва, Щёлковское шоссе д.3 строение 1 - Торговый Центр Город Хобби - 3 этаж, павильон 310, 105122'.match(/(?:[а-яА-ЯёЁ0-9\-\.\(\)]+\s?)+,?\s?(?:[а-яА-ЯёЁ0-9\-\.\(\)]+\s?)+(?:г|гор|город|п|пос|поселок|д|дер|деревня|ул|улица|пр|просп|пр-т

以下是JS中的调用:

'Москва, Щёлковское шоссе д.3 строение 1 - Торговый Центр Город Хобби - 3 этаж, павильон 310, 105122'.match(/(?:[а-яА-ЯёЁ0-9\-\.\(\)]+\s?)+,?\s?(?:[а-яА-ЯёЁ0-9\-\.\(\)]+\s?)+(?:г|гор|город|п|пос|поселок|д|дер|деревня|ул|улица|пр|просп|пр-т|проспект|п|пл|площадь|ал|аллея|бул|б-р|дор|наб|пер|пр|пр-д|туп|ш|шос|шоссе|к|кор|корп|корпус|стр|строение|зд|зд-е|здание|вор|ворота|д|дом|секция)\.?\s?,?\s?(?:г|гор|город|п|пос|поселок|д|дер|деревня|ул|улица|пр|просп|пр-т|проспект|п|пл|площадь|ал|аллея|бул|б-р|дор|наб|пер|пр|пр-д|туп|ш|шос|шоссе|к|кор|корп|корпус|стр|строение|зд|зд-е|здание|вор|ворота|д|дом|секция)\.?\s?[а-яА-Я0-9ёЁ№\-\/()]+,?\s?(?:г|гор|город|п|пос|поселок|д|дер|деревня|ул|улица|пр|просп|пр-т|проспект|п|пл|площадь|ал|аллея|бул|б-р|дор|наб|пер|пр|пр-д|туп|ш|шос|шоссе|к|кор|корп|корпус|стр|строение|зд|зд-е|здание|вор|ворота|д|дом|секция)\.?\s?[а-яА-Я0-9ёЁ№\-\/()]+/gi)
它导致无限调用,所以控制台将被卡住。 我想这里有点问题,但找不到这个错误

另外,我认为这不是V8中的错误,所以伙计们,请看这个。 看起来瓶颈是最后一部分№\-\/()]+这将导致在循环中搜索匹配项

如何修复它?

此问题称为嵌套量词导致的问题:

让我们减少这部分

(?:[а-яА-ЯёЁ0-9\-\.\(\)]+\s?)+
更具可读性:

(?:[0-9]+\s?)+
现在想象一个像
12345
这样的数字。上面的正则表达式有几个与之匹配的选项:

12345
1234, 5
123, 45
123, 4, 5
12, 345
12, 3, 45
12, 34, 5
12, 3, 4, 5
[...]
如果正则表达式最初无法匹配,它必须尝试所有这些方法——毕竟,也许我们还没有尝试过的不同组合可能会起作用

因此,避免使用嵌套的量词,或确保它们不允许所有这些排列,例如,不要使
\s
可选:

(?:[а-яА-ЯёЁ0-9\-\.\(\)]+\s)+
或者通过向角色类添加空格:

[а-яА-ЯёЁ0-9\-.()\s]+
使嵌套变得不必要。

此问题称为嵌套量词导致的问题:

让我们减少这部分

(?:[а-яА-ЯёЁ0-9\-\.\(\)]+\s?)+
更具可读性:

(?:[0-9]+\s?)+
现在想象一个像
12345
这样的数字。上面的正则表达式有几个与之匹配的选项:

12345
1234, 5
123, 45
123, 4, 5
12, 345
12, 3, 45
12, 34, 5
12, 3, 4, 5
[...]
如果正则表达式最初无法匹配,它必须尝试所有这些方法——毕竟,也许我们还没有尝试过的不同组合可能会起作用

因此,避免使用嵌套的量词,或确保它们不允许所有这些排列,例如,不要使
\s
可选:

(?:[а-яА-ЯёЁ0-9\-\.\(\)]+\s)+
或者通过向角色类添加空格:

[а-яА-ЯёЁ0-9\-.()\s]+

使嵌套变得不必要。

(?:[а-Я-г-г0-9\-\.(\)]+\s?+
(?:[а-Я-г-г0-9\.[\]+\s])+
是的,我发现了这一点,现在我正在思考如何避免这些可选的空格、点和逗号。谢谢,这就是答案。你可能想把它们分开,比如
(?:[а-аА-Ягг0-9]+[-.()\s]+[а-аА-Яё0-9]*
,这将允许字母和标点结束字符串。是的,我发现了这个,现在我正在考虑如何避免这些可选的空格、点和逗号。谢谢,这就是答案。你可能想把它们分开,比如
(?:[а-аА-Яг0-9]+[-.()\s]+[а-ЯА-гг0-9]*
,这将允许字母和标点符号结束字符串。