Optional capture groups using NSRegularExpressions in fast

I want to have several capture groups, which may be optional, and I want to access the lines to which they correspond.

Something that looks / works like this:

let text1 = "something with foo and bar"
let text2 = "something with just bar"
let regex = NSRegularExpression(pattern: "(foo)? (bar)")

for (first?, second) in regex.matches(in:text1) {
   print(first) // foo
   print(second) // bar
}

for (first?, second) in regex.matches(in:text2) {
   print(first) // nil
   print(second) // bar
}
0
source share
1 answer

Getting captured subtext with is NSRegularExpressionnot so simple.

First of all, the result matches(in:range:)is equal [NSTextCheckingResult], and each NSTextCheckingResultdoes not match the type, for example (first?, second).

, NSTextCheckingResult rangeAt(_:). rangeAt(0) , , rangeAt(1) , rangeAt(2) ..

rangeAt(_:) NSRange, Swift Range. (location length) UTF-16 NSString.

, rangeAt(_:) NSRange(location: NSNotFound, length: 0) .

, - :

let text1 = "something with foo and bar"
let text2 = "something with just bar"
let regex = try! NSRegularExpression(pattern: "(?:(foo).*)?(bar)") //please find a better example...

for match in regex.matches(in: text1, range: NSRange(0..<text1.utf16.count)) {
    let firstRange = match.rangeAt(1)
    let secondRange = match.rangeAt(2)
    let first = firstRange.location != NSNotFound ? (text1 as NSString).substring(with: firstRange) : nil
    let second = (text1 as NSString).substring(with: secondRange)
    print(first) // Optioonal("foo")
    print(second) // bar
}

for match in regex.matches(in: text2, range: NSRange(0..<text2.utf16.count)) {
    let firstRange = match.rangeAt(1)
    let secondRange = match.rangeAt(2)
    let first = firstRange.location != NSNotFound ? (text2 as NSString).substring(with: firstRange) : nil
    let second = (text2 as NSString).substring(with: secondRange)
    print(first) // nil
    print(second) // bar
}
+1

Source: https://habr.com/ru/post/1685417/


All Articles