Home > Enterprise >  Find only full matches of substrings in a String
Find only full matches of substrings in a String

Time:10-05

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.

  • Related