为什么这段代码会导致 Node.js 停止响应 - JavaScript Bug?

6

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

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

3
"stuck" 是什么意思?你在控制台中输入后它就卡住了吗? - XCS
8
由于 (([\u00C0-\u1FFF\u2C00-\uD7FF]+[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]*)+) 部分引起了“灾难性回溯”,导致问题出现。有关“灾难性回溯”的更多详细信息请参见此处。正则表达式的实际要求是什么? - Wiktor Stribiżew
1个回答

8
您的正则表达式因为 灾难性回溯 (请参考此处演示您的正则表达式),其中的 (([\u00C0-\u1FFF\u2C00-\uD7FF]+[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]*)+) 部分导致了回溯问题。由于 [^a-z\u00C0-\u1FFF\u2C00-\uD7FF]* 可以匹配零个字符,您基本上有一个经典的类似于 (a+)+ 的模式(参见:([\u00C0-\u1FFF\u2C00-\uD7FF]+)+)造成了回溯问题。
为了解决这个问题,您需要确保子模式在组内是必须的,并将*量词应用于整个组:
^([\u00C0-\u1FFF\u2C00-\uD7FF]+(?:[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]+[\u00C0-\u1‌​FFF\u2C00-\uD7FF]+)*) [a-z]+[^\u00C0-\u1FFF\u2C00-\uD7FF]*$

请查看 正则表达式演示

[\u00C0-\u1FFF\u2C00-\uD7FF]+(?:[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]+[\u00C0-\u1‌​FFF\u2C00-\uD7FF]+)* 匹配:

  • [\u00C0-\u1FFF\u2C00-\uD7FF]+ - 一个或多个来自[\u00C0-\u1FFF\u2C00-\uD7FF]范围内的字符
  • (?:[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]+[\u00C0-\u1‌​FFF\u2C00-\uD7FF]+)* - 零个或多个序列:
    • [^a-z\u00C0-\u1FFF\u2C00-\uD7FF]+ - 一个或多个不属于a-z\u00C0-\u1FFF\u2C00-\uD7FF范围内字符的字符
    • [\u00C0-\u1‌​FFF\u2C00-\uD7FF]+ - 一个或多个来自\u00C0-\u1‌​FFF\u2C00-\uD7FF范围内的字符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接