Swift和正则表达式,cpu因为某些字符串而变得混乱

时间:2015-11-05 05:43:15

标签: regex swift nsregularexpression

我希望将本地化线与正则表达式匹配。除了尝试匹配此字符串外,一切正常。您可以将代码放在操场上以查看它不会停止,或者在空白项目中查看cpu将100%停留并停留在“let match”行。现在有趣的是,如果你删除它的最后一个单词。我不知道是否适用于中文或其他奇怪的字符,这是希腊语。

<say>

稍后编辑:它实际上与字符类型无关,但字数。放在右侧的这个字符串也不起作用:'jhg jhgjklkhjkh hhhhh hhh'

3 个答案:

答案 0 :(得分:2)

您在(.*)+中嵌套了导致catastrophic backtracking的量词(我建议您阅读该文章)。问题是当子表达式失败时,正则表达式引擎会回溯以测试另一个替代方案。嵌套量词意味着主题字符串中的每个字符都会有一个指数的尝试次数:它将测试(.*)+的所有重复,并且对于每个重复.*

为了避免这种情况,请使用尽可能具体定义的模式:

"\"([^\"]+)\"[ ]*=[ ]*\"([^\"]*)\";"
  • \"([^\"]+)\"匹配
    • 开场"
    • [^\"]+除引号外的任意数量的字符。将+更改为*以允许空字符串。
    • 结束"

<强>代码

let lineContent = "\"key\" = \" Χρήση παλιάς συνόμευση\";"
if let r = try? NSRegularExpression(pattern: "\"([^\"]+)\"[ ]*=[ ]*\"([^\"]*)\";", options: NSRegularExpressionOptions()) {
    let match = r.matchesInString(
        lineContent,
        options: NSMatchingOptions(), 
        range: NSMakeRange(0, lineContent.characters.count)
    )

    for index in 1..<match[0].numberOfRanges {
        print((lineContent as NSString).substringWithRange(match[0].rangeAtIndex(index)))
    }
}

SwiftStub demo

答案 1 :(得分:1)

正如评论中已经提到的,.*+导致了灾难性的回溯,导致CPU使用率过高(一般情况下,无法匹配)。

而不是使用像

这样的模式
\"(.*)+\"

因为,你匹配双引号之间的所有内容,使用否定的字符集:

\"([^\"]+)\"

答案 2 :(得分:1)

根据上面的评论 - 将嵌套的(.*)+替换为惰性版本 - (.*?)