I have a string extension:
extension String {
func split(usingRegex pattern: String) -> [String] {
let regex = try! NSRegularExpression(pattern: pattern)
let matches = regex.matches(in: self, range: NSRange(0..<utf16.count))
let ranges = [startIndex..<startIndex] + matches.map{Range($0.range, in: self)!} + [endIndex..<endIndex]
return (0...matches.count).map {String(self[ranges[$0].upperBound..<ranges[$0+1].lowerBound])}
}
}
and I use it like this:
var string = "Hello45playground23today"
var output = string.split(usingRegex: "[0-9]+")
the output is:
["Hello", "playground", "today"]
But what I need is:
["Hello", "45", "playground", "23", "today"]
Is there a way to achieve that in Swift?
Your code adds only the substrings between the matches (and before the first match and after the last match) to the result. What you need is also the substrings for the matches themselves. This can be done by creating an array with all indices where a match starts or ends, and then taking all substrings between consecutive indices:
extension String {
func split(usingRegex pattern: String) -> [String] {
let regex = try! NSRegularExpression(pattern: pattern)
let matches = regex.matches(in: self, range: NSRange(startIndex..., in: self))
let splits = [startIndex]
+ matches
.map { Range($0.range, in: self)! }
.flatMap { [ $0.lowerBound, $0.upperBound ] }
+ [endIndex]
return zip(splits, splits.dropFirst())
.map { String(self[$0 ..< $1])}
}
}
Example:
let string = "Hello45playground23today"
let output = string.split(usingRegex: "[0-9]+")
print(output) // ["Hello", "45", "playground", "23", "today"]
The same can be done with an explicit loop (less sophisticated, but perhaps better readable):
extension String {
func split(usingRegex pattern: String) -> [String] {
let regex = try! NSRegularExpression(pattern: pattern)
let matches = regex.matches(in: self, range: NSRange(startIndex..., in: self))
var result: [String] = []
var pos = startIndex
for match in matches {
let range = Range(match.range, in: self)!
result.append(String(self[pos..<range.lowerBound]))
result.append(String(self[range]))
pos = range.upperBound
}
result.append(String(self[pos...]))
return result
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With