我正在关注Shippable CI's docs并使用下面的playground文件:
http://www.raywenderlich.com/86205/nsregularexpression-swift-tutorial
帮助查找匹配项,但我需要能够排除某些结果。
基本上我看的是以下模式:
let thenotClasses = "*121:32, Malachi 22:66 , 32:434, 16:111 , 17:11 , John 13:14, Verse 41:29, Great 71:21"
listMatches("\\d\\d?\\d?:\\d\\d?\\d?", inString: thenotClasses)
我得到所有数字:数字匹配,但是,我真正想做的是告诉它排除任何前缀为' *'或匹配前面带有" Malachi"或"约翰"但包括其余的
所以在这种情况下我希望匹配返回:
[32:434, 16:111 , 17:11 , 41:29 and 71:21]
任何帮助都会非常感激,愿上帝保佑:)
答案 0 :(得分:1)
一个RegEx模式在匹配某些单词之前使匹配失效很难写,主要是因为正则表达式引擎是贪婪的所以它可以从下一个数字开始。
如果你使用负面的后视:
(?<!\*|Malachi |John )(\d+:\d+)
这表示“匹配数字前面没有*
,Malachi
或John
”匹配将从下一个数字开始。例如,在Malachi 22:66
中,它会捕获2:66
。
我在Regex使用中看到的最常见的陷阱是将所有内容委托给正则表达式引擎。它确实很强大,但你忘了你也有更灵活的编程语言,可以调用正则表达式。
这是一个将两者混合在一起的想法:捕获任何number:number
并检查它前面的内容。如果匹配前面有*
或Malachi
或John
,则排除匹配。
模式:
(\*|Malachi |John )?(\d+:\d+)
(\*|Malachi |John ) - match a *, Malachi or John and put it into capture group 1
? - make the first capture group optional
(\d+:\d+) - match the verse and put it into capture group 2
代码:
let str = "*121:32, Malachi 22:66 , 32:434, 16:111 , 17:11 , John 13:14, Verse 41:29, Great 71:21"
let s = str as NSString // NSString is easier to work with Regex
let regex = try! NSRegularExpression(pattern: "(\\*|Malachi |John )?(\\d+:\\d+)", options: [])
var verses = [String]()
regex.enumerateMatchesInString(str, options: [], range: NSMakeRange(0, str.characters.count)) { result, flags, stop in
// Check that the first capture group is not found. Otherwise, return
guard let result = result where result.rangeAtIndex(1).location == NSNotFound else {
return
}
// When the first capture group is not found, add the second capture, group
// i.e. the verse number, to the result list
verses.append(s.substringWithRange(result.rangeAtIndex(2)))
}
print(verses)