使用NSRegularExpression排除某些匹配项

时间:2016-02-15 07:40:13

标签: ios regex swift nsregularexpression

我正在关注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]

任何帮助都会非常感激,愿上帝保佑:)

1 个答案:

答案 0 :(得分:1)

一个RegEx模式在匹配某些单词之前使匹配失效很难写,主要是因为正则表达式引擎是贪婪的所以它可以从下一个数字开始。

如果你使用负面的后视:

(?<!\*|Malachi |John )(\d+:\d+)

这表示“匹配数字前面没有*MalachiJohn”匹配将从下一个数字开始。例如,在Malachi 22:66中,它会捕获2:66

我在Regex使用中看到的最常见的陷阱是将所有内容委托给正则表达式引擎。它确实很强大,但你忘了你也有更灵活的编程语言,可以调用正则表达式。

这是一个将两者混合在一起的想法:捕获任何number:number并检查它前面的内容。如果匹配前面有*MalachiJohn,则排除匹配。

模式:

(\*|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)