Swift:正则表达式搜索for循环未进行

时间:2019-03-18 10:26:42

标签: swift regex

我正在循环内执行正则表达式搜索,但是我的实现似乎停滞了,即搜索无法进行到下一个周期。

//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个字符。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

您使用的([a-zA-Z0-9\-\_]*)*[sS]uper([a-zA-Z0-9\-\_]*)*模式效率很低,并且充满了catastrophic backtracking。当您将无限长的模式(如a+a*)放置在组中并为其设置无限量词(例如(a+)+)时,不在正则表达式的末尾,对于部分但不完全匹配模式的字符串来说,灾难性的回溯迫在眉睫。

请参见demo of your pattern与诸如Super之类的短字符串相对应。看,正则表达式引擎实际上很难确保Super是该模式的正确匹配,并且红色箭头表示回溯:

enter image description here

现在,如果解开嵌套的量化模式并使用[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_-]*