AFAIK there is no native Swift split method that allows you to keep the delimiters. You will need to implement your own split method extending Collection. Special thanks for @MartinR and @Rob for the code review:
extension Collection {
func splitAndKeep(
maxSplits: Int = .max,
omittingEmptySubsequences: Bool = true,
whereSeparator isSeparator: (Element) throws -> Bool
) rethrows -> [SubSequence] {
precondition(maxSplits >= 0, "maxSplits can not be negative")
if isEmpty { return [] }
var subsequences: [SubSequence] = []
var lowerBound = startIndex
func appendAndAdvance(with upperBound: Index) {
let range = lowerBound..<upperBound
if !omittingEmptySubsequences || !range.isEmpty {
subsequences.append(self[range])
lowerBound = upperBound
}
}
while
var upperBound = try self[lowerBound...].firstIndex(where: isSeparator),
subsequences.count < maxSplits {
appendAndAdvance(with: upperBound)
if subsequences.count == maxSplits {
break
}
formIndex(after: &upperBound)
appendAndAdvance(with: upperBound)
}
appendAndAdvance(with: endIndex)
return subsequences
}
}
let string = "*(22+13)/"
let delimiters = Set<Character>("{+-/*()%}.")
let ss = string.splitAndKeep(whereSeparator: delimiters.contains) // ["*", "(", "22", "+", "13", ")", "/"]
let ss1 = string.splitAndKeep(maxSplits: 0, whereSeparator: delimiters.contains) // ["*(22+13)/"]
let ss2 = string.splitAndKeep(maxSplits: 1, whereSeparator: delimiters.contains) // ["*", "(22+13)/"]
let ss3 = string.splitAndKeep(maxSplits: 2, whereSeparator: delimiters.contains) // ["*", "(", "22+13)/"]
let ss4 = string.splitAndKeep(omittingEmptySubsequences: false, whereSeparator: delimiters.contains) // ["", "*", "", "(", "22", "+", "13", ")", "", "/", ""]["", "*", "", "(", "22", "+", "13", ")", "", "/", ""]
let ss5 = string.splitAndKeep(maxSplits: 0, omittingEmptySubsequences: false, whereSeparator: delimiters.contains) // ["*(22+13)/"]
let ss6 = string.splitAndKeep(maxSplits: 1, omittingEmptySubsequences: false, whereSeparator: delimiters.contains) // ["", "*(22+13)/"]
let ss7 = string.splitAndKeep(maxSplits: 2, omittingEmptySubsequences: false, whereSeparator: delimiters.contains) // ["", "*", "(22+13)/"]