Say I have a string "45 minutes. 5 minutes", and I want to find the range of the "5 minutes".
let example = "45 minutes. 5 minutes"
let range = example.range(of: "5 minutes")
Instead of returning a range matching the standalone "5 minutes", it matches the end of the "45".
let example = "45 minutes. 5 minutes"
|–––––––| // ← This is the match
|–––––––| // ← This is what I am after
So how would I find the range of what is technically the second occurrence of the string.
CodePudding user response:
You could search backwards
let example = "45 minutes. 5 minutes"
let range = example.range(of: "5 minutes", options: .backwards)
or with a little help of Regular Expression if the second occurrence is exactly the end of the string
let range = example.range(of: "5 minutes$", options: .regularExpression)
or with a word boundary specifier if it's not the end of the string
let range = example.range(of: "\\b5 minutes", options: .regularExpression)
Edit:
As you are apparently looking for the ranges of all matches – which you didn't mention in the question – you can do this with real Regular Expression
let example = "45 minutes. 5 minutes"
let regex = try! NSRegularExpression(pattern: "5 minutes")
let matches = regex.matches(in: example, range: NSRange(example.startIndex..., in: example))
.compactMap{Range($0.range, in: example)}
CodePudding user response:
Figured it out!
I store matches as I find them in an array,
let previousMatches = [Range<String.Index>]()
Then as I search for a new match, I do this:
var myString = "45 minutes. 5 minutes"
var searchString = "5 minutes"
var searchRange: Range<String.Index>?
if let previousMatch = self.previousMatches.last {
searchRange = previousMatch.upperBound ..< myString.endIndex
}
let match = myString.range(of: "5 minutes", range: searchRange)
If that runs twice, it gets both matches.