为什么这个代码卡住node.js – 在Javascript上的错误?

我试图运行这个正则expression式,但它卡住了我的控制台。 为什么?

var str = "Шедевры православной музыки - 20 золотых православных песен"; str.match(/^(([\u00C0-\u1FFF\u2C00-\uD7FF]+[^az\u00C0-\u1FFF\u2C00-\uD7FF]*)+) [az]+[^\u00C0-\u1FFF\u2C00-\uD7FF]*$/i); 

你的正则expression式会导致灾难性的回溯 (见这里的正则expression式演示 ),因为(([\u00C0-\u1FFF\u2C00-\uD7FF]+[^az\u00C0-\u1FFF\u2C00-\uD7FF]*)+) 。 由于[^az\u00C0-\u1FFF\u2C00-\uD7FF]*可以匹配零个字符,所以基本上有一个经典的(a+)+样式(cf: ([\u00C0-\u1FFF\u2C00-\uD7FF]+)+ )导致回溯问题。

为了摆脱它,你需要确保分组内的子模式是强制性的,在整个分组中应用一个*量词:

 ^([\u00C0-\u1FFF\u2C00-\uD7FF]+(?:[^az\u00C0-\u1FFF\u2C00-\uD7FF]+[\u00C0-\u1‌​FFF\u2C00-\uD7FF]+)*) [az]+[^\u00C0-\u1FFF\u2C00-\uD7FF]*$ 

请参阅正则expression式演示

这里, [\u00C0-\u1FFF\u2C00-\uD7FF]+(?:[^az\u00C0-\u1FFF\u2C00-\uD7FF]+[\u00C0-\u1‌​FFF\u2C00-\uD7FF]+)*火柴:

  • [\u00C0-\u1FFF\u2C00-\uD7FF]+ – 一个或多个来自[\u00C0-\u1FFF\u2C00-\uD7FF]范围的[\u00C0-\u1FFF\u2C00-\uD7FF]
  • (?:[^az\u00C0-\u1FFF\u2C00-\uD7FF]+[\u00C0-\u1‌​FFF\u2C00-\uD7FF]+)* – 零个或多个序列:
    • 一个或多个不同于az\u00C0-\u1FFF\u2C00-\uD7FF范围的az\u00C0-\u1FFF\u2C00-\uD7FF
    • [\u00C0-\u1‌​FFF\u2C00-\uD7FF]+ – 一个或多个来自\u00C0-\u1‌​FFF\u2C00-\uD7FF范围的\u00C0-\u1‌​FFF\u2C00-\uD7FF