2016-02-17 13 views
6

我试图运行这个正则表达式,但它卡住了我的控制台。为什么?为什么此代码卡住node.js - Javascript上的错误?

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

你是什么意思卡住?你在他的控制台输入这个,它会冻结? – Cristy

+8

由于(([\ u00C0- \ u1FFF \ u2C00- \ uD7FF] + [^ az \ u00C0- \ u1FFF \]导致[灾难性回溯](https://regex101.com/r/eT6gL3/1) u2C00- \ uD7FF] *)+)'部分。更多关于[灾难性回溯的细节可以在这里找到](http://www.regular-expressions.info/catastrophic.html)。正则表达式的实际要求是什么? –

+1

你是在找[[^([\ u00C0- \ u1FFF \ u2C00- \ uD7FF] +(?:[^ az \ u00C0- \ u1FFF \ u2C00- \ uD7FF] + [\ u00C0- \ u1FFF \ u2C00- \ uD7FF] +)*)[az] + [^ \ u00C0- \ u1FFF \ u2C00- \ uD7FF] * $'](https://regex101.com/r/eT6gL3/2)? –

回答

8

您正则表达式导致catastrophic backtracking(见a demo of your regex here)由于(([\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]*$ 

regex demo

这里, [\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]+ - 从\u00C0-\u1‌​FFF\u2C00-\uD7FF范围的一个或多个字符 - 比那些来自a-z\u00C0-\u1FFF\u2C00-\uD7FF范围
    • [\u00C0-\u1‌​FFF\u2C00-\uD7FF]+其他一个或多个字符。
相关问题