我正在循环内执行正则表达式搜索,但是我的实现似乎停滞了,即搜索无法进行到下一个周期。
//At a function where I'm performing my regex search
let pattern = "([a-zA-Z0-9\\-\\_]*)*[sS]uper([a-zA-Z0-9\\-\\_]*)*"
for text in array {
let matches = listMatches(for: pattern, inString: text)
print(matches)
}
print("Regex done") //When a break point is placed here, this never gets executed
func listMatches(for pattern: String, inString string: String) -> [String] {
guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
return []
}
let range = NSRange(string.startIndex..., in: string)
let matches = regex.matches(in: string, options: [], range: range)
return matches.map {
let range = Range($0.range, in: string)!
return String(string[range])
}
}
我在array
中有大约5个文本,而print(matches)
将打印matches
中的3个文本。 for
循环永远不会超过第4个或第5个周期,而print("Regex done")
也永远不会执行。 text
的大小通常约为1000个字符。有什么建议吗?
答案 0 :(得分:1)
您使用的([a-zA-Z0-9\-\_]*)*[sS]uper([a-zA-Z0-9\-\_]*)*
模式效率很低,并且充满了catastrophic backtracking。当您将无限长的模式(如a+
或a*
)放置在组中并为其设置无限量词(例如(a+)+
)时,和不在正则表达式的末尾,对于部分但不完全匹配模式的字符串来说,灾难性的回溯迫在眉睫。
请参见demo of your pattern与诸如Super
之类的短字符串相对应。看,正则表达式引擎实际上很难确保Super
是该模式的正确匹配,并且红色箭头表示回溯:
现在,如果解开嵌套的量化模式并使用[a-zA-Z0-9_-]*[sS]uper[a-zA-Z0-9_-]*
,请参见this demo,然后将步数从167减少到13,请检查模式变得有多快。请注意,您不需要来转义_
字符(它是一个 word 字符),并且不必在字符类内部转义-
(如果它位于字符集的开始/结尾)。课。
如果您使用.caseInsensitive
option(例如options: [ .caseInsensitive ]
),甚至可以将模式缩短为[a-z0-9_-]*super[a-z0-9_-]*
。