5

There is a clever 1st answer given here for splitting swift string with a regex expression

split string answer

However it keeps the searched text within the array of answers. I'm trying to do a similar thing, but ignoring the characters acting as separators (e.g. just like the swift split function, but just with a regex expression as the separator).

As an example: regex would be something like

"\\\||Z|ZY"

and when applied to string of "hi|thisZshouldZYbe|separated" then you would get back an array

["hi", "this", "should", "be", "separated"]

NB. The regex is adapted to the swift NSRegularExpression format with the double escape. In regular regex it would just be "\||Z|ZY" Also NB the regex contains the vertical line symbol not the letter "l"

You prob don't need to do too many tweaks to the original to make work.

2 Answers 2

13

You can define an extension like this:

extension String {
    func split(usingRegex pattern: String) -> [String] {
        //### Crashes when you pass invalid `pattern`
        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])}
    }
}

let str = "hi|thisZshouldZYbe|separated"
let separator = "\\||ZY?"
let result = str.split(usingRegex: separator)
print(result) //->["hi", "this", "should", "be", "separated"]

The above code does not work as you expect when you use "\\||Z|ZY", but I think you can modify your pattern to fit into this extension.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. I think I can follow what you've done in the code - and makes sense. Very concise! and I didn't realise you could use map like that on the return statement - so many thanks. It's this conversion between NSRanges and normal ranges which makes it so tricky. I need to test once some other errors corrected.
I've tested this and it is working well for my purposes. Thank you
3

My suggestion is to create an UUID string as separator, then replace the occurrences of the regex pattern with this UUID string and split the string.

let string = "hi|thisZshouldZYbe|separated"
let uuid = UUID().uuidString
let result = string.replacingOccurrences(of: "\\||ZY?", with: uuid, options: .regularExpression).components(separatedBy: uuid)

Your pattern works only in another order of the OR parts ("\\||ZY|Z")

2 Comments

Why not use UUID in Swift?
@rmaddy Yes, why not? 😉

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.