我对如何在Swift中使用NSRegularExpression类感到困惑,尤其是:lengthNSRange参数。

一些教程说NSRegularExpression应该只应用于NSString实例,而另一些教程说只要将utf8.countutf16.count提供给:lengthNSRange参数,就可以将其应用于(Swift)字符串实例:

var str : String = "#tweak #wow #gaming"
if let regex = try? NSRegularExpression(pattern: "#[a-z0-9]+", options: .caseInsensitive) {
    regex.matches(in: str, options: [], range: NSRange(location: 0, length: str.utf8.count)).map {
        print(str.substring(with: $0.range))
    }
}

以下是此source的引号:

由于在Swift和
Objective-C,您需要为NSRange实例提供一个
来自NSString的字符串长度,而不是来自String的字符串长度。

粗略地说,这是因为NSString使用固定宽度编码
而String使用可变宽度编码。

此外,就在Swift中记录NSRegularExpression类而言,以下文档真的是Apple能够做到的最好的选择吗?

https://developer.apple.com/documentation/foundation/nsregularexpression

我至少希望得到该类的属性和方法的列表,但它仅显示一些示例。还有更详尽的文档吗?

最佳答案

utf16计数正确,而不是utf8计数。或者,最好使用便捷初始化程序,这些初始化程序将RangeString.Index转换为NSRange:

let range = NSRange(str.startIndex..., in: str)

并将NSRange转换为String.Range:
let range = Range(nsRange, in: str)

因此,将它们放在一起:
let str = "#tweak #wow #gaming"
if let regex = try? NSRegularExpression(pattern: "#[a-z0-9]+", options: .caseInsensitive) {
    let nsRange = NSRange(str.startIndex..., in: str)
    let strings = regex.matches(in: str, range: nsRange).compactMap {
        Range($0.range, in: str).map { str[$0] }
    }
    print(strings)
}

请参阅WWDC 2017 Efficient Interactions with Frameworks,其中讨论了(a)我们在处理范围时对UTF16的历史使用; (b)我们不必再这样做了。

关于ios - 使用(Swift)字符串为NSRegularExpression提供给NSRange的正确的length:参数是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57525620/

10-11 20:22