我对如何在Swift中使用NSRegularExpression
类感到困惑,尤其是:length
的NSRange
参数。
一些教程说NSRegularExpression应该只应用于NSString实例,而另一些教程说只要将utf8.count
或utf16.count
提供给:length
的NSRange
参数,就可以将其应用于(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计数。或者,最好使用便捷初始化程序,这些初始化程序将Range
的String.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/