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 } }