4

I'm trying to search a String for regex using the following snippet (it's in an extension for String):

var range = self.startIndex..<self.endIndex

while range.lowerBound < range.upperBound {
    if let match = self.range(of: regex, options: .regularExpression, range: range, locale: nil) {

        print(match)
        range = ????? <============  this line, how do I update the range?
    }
}

It will correctly find the first occurance, but then I don't know how to change the range to the position of the match to search the remainder of the string.

pkamb
  • 30,595
  • 22
  • 143
  • 179
koen
  • 4,902
  • 6
  • 42
  • 80
  • 1
    What are you trying to do inside that `while` loop? Seems like an infinite loop even if you can update the range. And I think using `NSRegularExpression` is a lot cleaner – Code Different Sep 02 '16 at 15:39
  • Point well taken, any suggestions how to make this loop work? I will look at `NSRegularExpression` as well. – koen Sep 02 '16 at 19:37
  • @MartinR: I ended up using `NSRegularExpression`. – koen Sep 22 '16 at 18:39

1 Answers1

6

lowerBound and upperBound are immutable properties of the range, so you have to create a new range, starting at match.upperBound.

Also the loop should terminate if no match is found. That can be achieved by moving the binding let match = ... into the where condition.

var range = self.startIndex..<self.endIndex
while range.lowerBound < range.upperBound,
    let match = self.range(of: regex, options: .regularExpression, range: range) {
        print(match) // the matching range
        print(self.substring(with: match)) // the matched string

        range = match.upperBound..<self.endIndex
}

This can still lead to an infinite loop if an empty string matches the pattern (e.g. for regex = "^"). This can be solved, but as an alternative, use NSRegularExpression to get a list of all matches (see for example Swift extract regex matches).

pkamb
  • 30,595
  • 22
  • 143
  • 179
Martin R
  • 510,973
  • 84
  • 1,183
  • 1,314