如何一次运行多个NSRegularExpression

时间:2018-11-02 09:54:24

标签: swift regex nsregularexpression

我有一堆NSRegularExpression,我想运行一次。有人知道该怎么做吗?

就目前而言,我是在.forEach中这样做的,出于性能方面的考虑,我认为这不是最好的主意

每个NSRegularExpression需要匹配一个不同的模式,匹配之后,我需要处理每种不同类型的匹配。例如,如果我与数组中的第一个正则表达式匹配,则需要做出与第二个正则表达式不同的东西...

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) }

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

如果使用捕获组和 OR 表达式将它们组合在一起,则可以将多个正则表达式评估为一个。

如果要搜索:languageObjective-CSwift字符串,则应使用以下格式:(language)|(Objective-C)|(Swift)。每个捕获组都有一个订单号,因此,如果在源字符串中找到language,则匹配对象将提供索引号。

您可以在此游乐场示例中使用代码:

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)")
})

如果运行它,结果是:

How many matches: 3

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

希望我能正确理解您的问题,并且这段代码对您有所帮助。