我在Cocoa应用程序中使用RKL来解析来自包装任务的日志语句。
模式:
(?:.+) \[.+?\] (.+) \[.+?\] logged in (?:.+)
测试数据:
2011-07-11 00:48:19 [INFO] Preparing spawn area: 97
2011-07-11 00:48:19 [INFO] Done (2175837000ns)! For help, type "help" or "?"
2011-07-11 00:48:42 [INFO] mikeyward [/127.0.0.1:59561] logged in with entity id blahblah
我在互联网上尝试的每一个RegEx测试人员都成功匹配第三行并捕获'mikeyward'。
Objective-C代码:
NSString *loggedInPattern = @"(?:.+) \\[.+?\\] (.+) \\[.+?\\] logged in (?:.+)";
NSArray *captures = [searchString arrayOfCaptureComponentsMatchedByRegex:loggedInPattern];
NSString *username = [captures objectAtIndex:0];
问题: 尽管已经检查以确保searchString有效且包含示例数据,但RKL无法匹配该行,更不用说捕获用户名了。在上面的例子中,引发了一个异常,因为带有零对象返回的捕获数组并且我没有进行错误检查:)
任何帮助理解为什么正则表达式检查员确认匹配和捕获但RKL错过了它将非常感激。
感谢〜
答案 0 :(得分:0)
您的匹配器只进行单线匹配。使用带有选项的版本并将其传递给RKLMultiline
答案 1 :(得分:0)
您的问题可能与this one有关,或者可能只是catastrophic backtracking的情况。在任何一种情况下,我的建议都是一样的:编写正则表达式,这样,没有一个量词具有重叠的影响范围。例如:
(?m)^[ 0-9:-]+\[[A-Z]+\] (\S+) \[[^\]]+\] logged in .+$
在你的正则表达式中,第一个(?:.+)
最初吞噬了行中的所有字符,只是为了让大部分字符都回来,所以其余的正则表达式都有机会匹配。另一方面,[ 0-9:-]+
只要看到一个不是空格,数字,冒号或连字符的字符就会停止消费。
如果下一个字符不是[
,则它不会再进一步,并且整体匹配尝试失败的速度比以前快得多。同样,[A-Z]+
无法突破结束]
,\S+
无法超越下一个空格,[^]] + stops before the next
] . I didn't change the final
。+`因为它已经完成了我们想要的东西,即消耗所有字符直到下一个换行符或文本结尾。
无论如何,这就是我写这个正则表达式的方法,但出于好奇,如果你保留正则表达式但是添加线锚会发生什么?
(?m)^(?:.+) \[.+?\] (.+) \[.+?\] logged in (?:.+)$
它仍然效率低下,但它可能会使无法正常工作与工作不正常之间存在差异。 :d