当输入字符串包含括号时,正则表达式挂起

时间:2016-02-22 13:10:18

标签: ruby regex

我有:

vv = /added:\s{0,}\d{1,2}\/\d{1,2}\/\d{4}|terminated:\s{0,}\d{1,2}\/\d{1,2}\/\d{4}|(?-mix:\((\w+([\p{P}\s]{,3}\w*)*)\))/i

以下是我的实验:

detail = "(value containts lorem ipsum lorum ipsum"
detail =~ vv

当我在输入字符串的开头尝试不带括号时,它可以工作。

detail = "value containts lorem ipsum lorum ipsum"
detail =~ vv
# => nil

1 个答案:

答案 0 :(得分:1)

您遇到的问题是灾难性的回溯。由于\w+([\p{P}\s]{,3}\w*)*包含嵌套零或更多量词([\p{P}\s]{,3}\w*)*,因此*会导致问题。问题出现是因为里面的部分都是可选的(=可以匹配空字符串)和量化。请参阅your regex demo,尝试添加一个符号并查看步数增加:在(value containt之后添加一个空格会将步数从65,742增加到102,610!添加1个符号会使演示崩溃。

\w+(?:[\p{P}\s]{1,3}\w+)*或甚至\w+(?:\W{1,3}\w+)*替换它应该可以解决问题,因为分组(...)构造中的子模式将不再匹配空字符串(但整个组将是可选的) ,零次或多次重复)。 [\p{P}\s]{1,3}需要至少1个标点符号或空格,\w+需要一个或多个单词字符。

另请注意,您不需要(?-mix:...)组,我已将其从我建议的模式中删除:您内部没有.(不需要m),没有可以写的字母是小写或大写(不需要i)并且模式中没有可忽略的空格(不需要x)。此外,{0,}量词等于*,我在开头替换了一两个。

使用

vv = /added:\s*\d{1,2}\/\d{1,2}\/\d{4}|terminated:\s*\d{1,2}\/\d{1,2}\/\d{4}|\((\w+(?:[\p{P}\s]{1,3}\w+)*)\)/i
detail = "(value containts lorem ipsum lorum ipsum"
detail =~ vv

请参阅Ruby demo