问题描述
我正在尝试使用正则表达式解析字符串,但在尝试提取子字符串中的所有信息时遇到了一些问题。我快完成了,但我在这一点上堆积如山:
对于这样的字符串:
[00/0/00,00:00:00] User: This is the message text and any other stuff
let line = "[00/0/00,00:00:00] User: This is the message text and any other stuff"
let result = line.match("(.+)\\s([\\S ]*):\\s(.*\n(?:[^-]*)*|.*)$")
extension String {
func match(_ regex: String) -> [[String]] {
let nsstring = self as Nsstring
return (try? NSRegularExpression(pattern: regex,options: []))?.matches(in: self,options: [],range: NSMakeRange(0,count)).map { match in
(0..<match.numberOfRanges).map { match.range(at: $0).location == NSNotFound ? "" : nsstring.substring(with: match.range(at: $0)) }
} ?? []
}
}
结果数组是这样的:
[["[00/0/00,00:00:00] User: This is the message text and any other stuff","[00/0/00,00:00:00]","User","This is the message text and any other stuff"]]
现在我的问题是,如果消息上有 ':'
,则结果数组不遵循相同的格式并破坏解析功能。
所以我想我在正则表达式中遗漏了一些情况,有人可以帮助我吗?提前致谢。
解决方法
在模式中,您使用了非常广泛匹配的部分。
例如,.+
将首先匹配到行尾,[\\S ]*
将匹配非空白字符或空格,而 [^-]*
匹配除 {{1 }}
它可能会中断的原因是广泛匹配首先匹配到字符串末尾。由于单个 -
在您的模式中是强制性的,它将从字符串的末尾回溯,直到它可以匹配 :
后跟一个空格,然后尝试匹配模式的其余部分。
在消息部分添加另一个 :
可能会导致回溯比您预期的更早停止,从而缩短消息组。
您可以使模式更精确一些,以便最后一部分也可以包含 :
而不会破坏组。
:
-
(\[[^][]*\])\s([^:]*):\s(.*)$
匹配组1 中从开始到结束方括号 -
[...]
匹配一个空白字符 -
\s
匹配 group 2 中除([^:]*):
之外的任何字符,然后匹配预期的:
-
:
匹配一个空白字符,并捕获组 3 中任意字符的 0 次以上
-
\s(.*)
字符串结束
(\[[^][]*\])
的部分