我有:
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
答案 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