【问题标题】:Why this code stuck node.js - Bug on Javascript?为什么这段代码卡住了 node.js - Javascript 上的错误?
【发布时间】:2016-05-29 00:59:06
【问题描述】:
我正在尝试运行此正则表达式,但它卡住了我的控制台。为什么?
var str = "Шедевры православной музыки - 20 золотых православных песен";
str.match(/^(([\u00C0-\u1FFF\u2C00-\uD7FF]+[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]*)+) [a-z]+[^\u00C0-\u1FFF\u2C00-\uD7FF]*$/i);
【问题讨论】:
标签:
javascript
regex
node.js
unicode
infinite-loop
【解决方案1】:
由于(([\u00C0-\u1FFF\u2C00-\uD7FF]+[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]*)+) 部分,您的正则表达式会导致catastrophic backtracking(请参阅a demo of your regex here)。由于[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]* 可以匹配零个字符,因此您基本上有一个类似于(a+)+ 的经典模式(参见:([\u00C0-\u1FFF\u2C00-\uD7FF]+)+),它会导致回溯问题。
要摆脱它,您需要确保子模式在分组内强制,并将* 量词应用于整个分组:
^([\u00C0-\u1FFF\u2C00-\uD7FF]+(?:[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]+[\u00C0-\u1FFF\u2C00-\uD7FF]+)*) [a-z]+[^\u00C0-\u1FFF\u2C00-\uD7FF]*$
见regex demo
这里,[\u00C0-\u1FFF\u2C00-\uD7FF]+(?:[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]+[\u00C0-\u1FFF\u2C00-\uD7FF]+)* 匹配:
-
[\u00C0-\u1FFF\u2C00-\uD7FF]+ - [\u00C0-\u1FFF\u2C00-\uD7FF] 范围内的一个或多个字符
-
(?:[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]+[\u00C0-\u1FFF\u2C00-\uD7FF]+)* - 零个或多个序列:
-
[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]+ - 除了a-z\u00C0-\u1FFF\u2C00-\uD7FF 范围之外的一个或多个字符
-
[\u00C0-\u1FFF\u2C00-\uD7FF]+ - \u00C0-\u1FFF\u2C00-\uD7FF 范围内的一个或多个字符。