I'm confused on how to use the NSRegularExpression
class in Swift, especially the :length
parameter of NSRange
.
Some tutorials say that NSRegularExpression should only be applied to NSString instances, while others say it's OK to apply it to (Swift) string instances as long as you provide utf8.count
or utf16.count
to :length
parameter of NSRange
:
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))
}
}
The following are quotes from this source :
Due to the way strings are handled differently in Swift and Objective-C, you will need to provide the NSRange instance with a string length from NSString, and not from String.
This is, roughly speaking, because NSString uses fixed-width encoding and String uses variable-width encoding.
Furthermore, is the following documentation really the best Apple can do with respect to documenting the NSRegularExpression
class in Swift?
https://developer.apple.com/documentation/foundation/nsregularexpression
I'd at least expect a list of properties and methods of the class, but it only show some examples. Is there any more elaborate documentation?
The utf16 count is correct, not the utf8 count. Or, best, use the convenience initializers, which convert a Range
of String.Index
to a NSRange
:
let range = NSRange(str.startIndex..., in: str)
And to convert NSRange
to String.Range
:
let range = Range(nsRange, in: str)
Thus, putting that together:
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)
}
See WWDC 2017Efficient Interactions with Frameworks , which talks about (a) our historical use of UTF16 when dealing with ranges; and (b) the fact that we don't have to do that any more.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.