swift:正規表現を使って文字検索してみました

概要

正規表現を使って文字検索してみました。

いろいろな方法があると思いますが、Stringクラスのextensionを使うのが簡単そうです。NSRegularExpression Class Referenceはわかりにくいですね。

iOS - Swift2.0で正規表現を簡単に扱う。 - Qiitaがわかりやすかったです。

import Foundation

extension String {
    func findAll(input: String) -> [String]? {
        do {
            let re = try NSRegularExpression(pattern: self, options: NSRegularExpressionOptions.CaseInsensitive)
            let matches = re.matchesInString(input, options: [], range:NSMakeRange(0, input.characters.count))
            var results: [String] = []
            for match in matches {
                results.append((input as NSString).substringWithRange(match.range))
            }
            return results
        } catch let error {
            print("\(error)")
            return nil
        }
    }
}
let input = "&l=99182670&m=99182671"
if let matches = "(\\d{8,})".findAll(input) {
    for match in matches {
        print(match)
    }
}

Performance

Performanceについて、以下のような記載がありますので、*や+を多く使う正規表現はパフォーマンスが悪い可能性があります。

NSRegularExpression implements a nondeterministic finite automaton matching engine. As such, complex regular expression patterns containing multiple * or + operators may result in poor performance when attempting to perform matches — particularly failing to match a given input. For more information, see the “Performance Tips” section of the ICU User Guide.

また、パフォーマンス観点では、オートマトン(NSRegularExpression)の作成コストが高いので使い回すことができるよう設計した方が良いかもしれません。

JavaだとPatternをstatic変数(例:Logicクラス)に持つことがあります。

関連資料