swiftstringnsrange

Find NSRanges of all substrings splitted by new lines


So I have this code finding Ranges substrings by splitting new lines:

let string = "hello\nhello"
let rangesSplittedByLines: [Range] = string.split(separator: "\n").compactMap {
    return string.range(of: $0)
}

But I need those ranges as NSRange. How would you get NSRange array of all substrings?


Solution

  • In the closure create an NSRange from Range<String.Index>

    let string = "hello\nhello"
    let rangesSplittedByLines: [NSRange] = string.split(separator: "\n").map {
        return NSRange(string.range(of: $0)!, in: string)
    }
    

    But there is another problem. The code returns [{0, 5}, {0, 5}] because range(of: returns always the range of the first match.

    This fixes the problem, it slices the string by moving the start index to the position after the most recent match

    let string = "hello\nhello"
    var startIndex = string.startIndex
    let rangesSplittedByLines: [NSRange] = string.split(separator: "\n").map {
        let subString = string[startIndex...]
        let swiftRange = subString.range(of: $0)!
        let nsRange = NSRange(swiftRange, in: string)
        startIndex = swiftRange.upperBound
        return nsRange
    }
    

    And there is no reason to bridge String to NSString explicitly.

    But as you want nsranges anyway Regular Expression like in Martin’s answer is much more efficient.