Brandon Bradley
Brandon Bradley

Reputation: 3378

How to capture words around regular expression pattern?

I have a String which is :

let s : String = "The dog ate the cat."

With the following pattern :

let p : NSRegularExpression = try! NSRegularExpression(pattern: "\\w( )?dog( )?\\w"), options: .CaseInsensitive)

My question is : How do I get the words before and after the pattern's occurrence?

This is my current implementation :

let t : [NSTextCheckingResults] = p.matchesInString(s, options: [], NSMakeRange(0, NSString(string: s).length))
print(String(t[0].URL!))

However this does not return the desired result.

What is wrong with my regular expression?

Upvotes: 0

Views: 79

Answers (1)

Code Different
Code Different

Reputation: 93141

Try this:

extension String {
    subscript (range: NSRange) -> String {
        let startIndex = self.startIndex.advancedBy(range.location)
        let endIndex = startIndex.advancedBy(range.length)

        return self[startIndex..<endIndex]
    }
}

let s = "The dog ate the cat."

let pattern = try! NSRegularExpression(pattern: "(\\w+)?\\s?dog\\s?(\\w+)?", options: [.CaseInsensitive])

let matches = pattern.matchesInString(s, options: [], range: NSMakeRange(0, s.characters.count))

for m in matches {
    print(s[m.rangeAtIndex(0)])

    let range1 = m.rangeAtIndex(1)
    if range1.location != NSNotFound {
        print("capture group 1:", s[range1])
    }

    let range2 = m.rangeAtIndex(2)
    if range2.location != NSNotFound {
        print("capture group 2:", s[range2])
    }
}

The extension to String is optional but it makes working with NSRange much easier. The 2 capture groups were made optional with (\\w+)? so it matches the following strings too:

// The dog ate the cat
The dog ate
capture group 1: the
capture group 2: ate

// dog ate my home work
dog ate
capture group 2: ate

// I love my dog
my dog
capture group 1: my

// dog
dog

Upvotes: 1

Related Questions