2

I have a bunch of NSRegularExpression and I want to run it once. Anyone knows how to do it ?

For the moment I do it in a .forEach, for performance reasons I do not think this is the best idea

Each NSRegularExpression needs to match a different pattern, after the matching I need to deal with each different kind of match. As example if I match with the first regex in my array I need to make something different from the second etc...

let test: String = "Stuff"
let range: NSRange = // a range

var regexes = [NSRegularExpression] = // all of my regexes
regexes.forEach { $0.matches(in: text, options: [], range: range) }

Thanks for you help

0xced
  • 25,219
  • 10
  • 103
  • 255
  • 2
    Without showing any of your NSRegularExpressions, the array or your current code it would be difficult to answer this.. Please edit the question to include your code in a [Minimal, Complete, and Verifiable](https://stackoverflow.com/help/mcve) example. – Theo Nov 02 '18 at 10:12
  • From what I have seen in Apple document regarding to `NSRegularExpression`, it seems that you won't be able to do it. However, how about doing all of matching stuffs concurrency with `GCD`? – RyanB Nov 02 '18 at 10:40
  • Thanks for your answers guys, I've update the answer @Theo – uligerri-6156 Nov 02 '18 at 10:48
  • @RyanB it can nice yeah – uligerri-6156 Nov 02 '18 at 10:48
  • "f I match with the first regex in my array I need to make something different from the second" Define different? What kind of operation do you want to do? Could you give a more explicit example? – Larme Nov 02 '18 at 12:45
  • @Larme For each regex I'll apply different text attributes to a label – uligerri-6156 Nov 02 '18 at 13:50

1 Answers1

0

You may be able to evaluate several regular expressions as one if you concatenate them using capture groups and an OR expressions.

If you want to search for: language, Objective-C and Swift strings you should use a pattern like this: (language)|(Objective-C)|(Swift). Each capture group has an order number, so if language is found in the source string the match object provides the index number.

You can used the code in this playground sample:

import Foundation

let sourceString: String = "Swift is a great language to program, but don't forget Objective-C."
let expresions = [ "language",     // Expression 0
                   "Objective-C",  // Expression 1
                   "Swift"         // Expression 2
                 ]
let pattern = expresions
                .map { "(\($0))" }
                .joined(separator: "|") // pattern is defined as : (language)|(Objective-C)|(Swift)

let regex = try? NSRegularExpression(pattern: pattern, options: [])
let matches = regex?.matches(in: sourceString, options: [],
                         range: NSRange(location: 0, length: sourceString.utf16.count))
let results = matches?.map({ (match) -> (Int, String) in // Array of type (Int: String) which
                                                         // represents index of expression and
                                                         // string capture
    let index = (1...match.numberOfRanges-1) // Go through all ranges to test which one was used
                 .map{ Range(match.range(at: $0), in: sourceString) != nil ? $0 : nil }
                 .compactMap { $0 }.first! // Previous map return array with nils and just one Int
                                           // with the correct position, lets apply compactMap to
                                           // get just this number

    let foundString = String(sourceString[Range(match.range(at: 0), in: sourceString)!])
    let position = match.range(at: 0).location
    let niceReponse = "\(foundString) [position: \(position)]"
    return (index - 1, niceReponse) // Let's substract 1 to index in order to match  zero based array index
})

print("Matches: \(results?.count ?? 0)\n")
results?.forEach({ result in
    print("Group \(result.0): \(result.1)")
})

If you run it the result is:

How many matches: 3

Expression 2: Swift [position: 0]
Expression 0: language [position: 17]
Expression 1: Objective-C [position: 55]

I hope I understood correctly your question and this code helps you.

Aaron Cyrman
  • 556
  • 3
  • 13