Swift: 正規表現を使って文字列を抜き出す(グループ化対応)

1 min read読了の目安(約800字

Javascriptのmatchみたいなことをしたい。

import Foundation

extension String {
    func match(_ pattern: String) -> [String] {
        guard let regex = try? NSRegularExpression(pattern: pattern),
              let matched = regex.firstMatch(in: self, range: NSRange(location: 0, length: self.count))
        else { return [] }
        return (0 ..< matched.numberOfRanges).map {
            NSString(string: self).substring(with: matched.range(at: $0))
        }
    }
}
使用例
let str = "Hello --<Kyome:1234>--"
let res = str.match(#"--<(([a-zA-Z]+):\d+)>--"#)
Swift.print(res)
["--<Kyome:1234>--", "Kyome:1234", "Kyome"]

一致文字列が配列で手に入る。グループ化している場合は大きい部分一致から細かい部分一致に向かって配列に格納されていく。
正規表現文字列を書くときは、正規表現のエスケープとSwiftのエスケープの双方を考えないといけなくなると面倒くさいので、Swift側のエスケープを無視できるように文字列は""ではなく#""#で囲うと良い。