为什么这段代码卡住了node.js - Javascript上的Bug?

Mos*_*tov 6 javascript regex unicode infinite-loop node.js

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

var str = "??????? ???????????? ?????? - 20 ??????? ???????????? ?????";
str.match(/^(([\u00C0-\u1FFF\u2C00-\uD7FF]+[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]*)+) [a-z]+[^\u00C0-\u1FFF\u2C00-\uD7FF]*$/i);
Run Code Online (Sandbox Code Playgroud)

Wik*_*żew 8

由于部分原因,你的正则表达式导致了灾难性的回溯(参见你的正则表达式的演示)(([\u00C0-\u1FFF\u2C00-\uD7FF]+[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]*)+).因为[^a-z\u00C0-\u1FFF\u2C00-\uD7FF]*可以匹配零个字符,你基本上有一个(a+)+类似于经典的模式(cf :) ([\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]*$
Run Code Online (Sandbox Code Playgroud)

请参阅正则表达式演示

在这里,[\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.