以下是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ёЁ№\-\/()]+
。
我该如何解决?
答案 0 :(得分:2)
此问题称为catastrophic backtracking,由嵌套量词产生:
让我们减少这部分
(?:[а-яА-ЯёЁ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]+
不需要嵌套。