如何在具有可变宽度Unicode字符的Swift字符串上使用NSRegularExpression?

Nat*_*ook 9 regex objective-c nsregularexpression swift

我无法NSRegularExpression在字符串上匹配模式,其中包含更宽的(?)Unicode字符.看起来问题是范围参数--Swift计算单个Unicode字符,而Objective-C将字符串视为由UTF-16代码单元组成.

这是我的测试字符串和两个正则表达式:

let str = "dogcow"
let dogRegex = NSRegularExpression(pattern: "d.g", options: nil, error: nil)!
let cowRegex = NSRegularExpression(pattern: "c.w", options: nil, error: nil)!
Run Code Online (Sandbox Code Playgroud)

我可以匹配第一个正则表达式没有问题:

let dogMatch = dogRegex.firstMatchInString(str, options: nil, 
                   range: NSRange(location: 0, length: countElements(str)))
println(dogMatch?.range)  // (0, 3)
Run Code Online (Sandbox Code Playgroud)

但是第二个失败了相同的参数,因为我发送它的范围(0 ... 7)不足以涵盖整个字符串,只要NSRegularExpression有关:

let cowMatch = cowRegex.firstMatchInString(str, options: nil, 
                   range: NSRange(location: 0, length: countElements(str)))
println(cowMatch.range)  // nil
Run Code Online (Sandbox Code Playgroud)

如果我使用不同的范围,我可以使匹配成功:

let cowMatch2 = cowRegex.firstMatchInString(str, options: nil, 
                    range: NSRange(location: 0, length: str.utf16Count))
println(cowMatch2?.range)  // (7, 3)
Run Code Online (Sandbox Code Playgroud)

但后来我不知道如何从字符串中提取匹配的文本,因为该范围超出了Swift字符串的范围.

Nat*_*ook 10

原来你可以用火扑灭.使用Swift-native字符串的utf16Count属性和- notsubstringWithRange:方法- 获得正确的结果.这是完整的工作代码:NSString String

let str = "dogcow"
let cowRegex = NSRegularExpression(pattern: "c.w", options: nil, error: nil)!

if let cowMatch = cowRegex.firstMatchInString(str, options: nil,
                      range: NSRange(location: 0, length: str.utf16Count)) {
    println((str as NSString).substringWithRange(cowMatch.range))
    // prints "cow"
}
Run Code Online (Sandbox Code Playgroud)

(我在写这个问题的过程中想到了这一点;为橡皮鸭调试得到一分.)