Swift Regex における Regex の主な生成方法について調べたので、3つ紹介します。
リテラル
最もシンプルな生成方法は、リテラルで書くことです。
リテラルなら 正規表現の構文 や キャプチャの数 などが静的にチェックされます。
let text = "現在の時刻は18時30分です。"
let regex = /(\d+)時(\d+)分/
if let match = text.firstMatch(of: regex) {
match.0 == "18時30分"
match.1 == "18"
match.2 == "30"
}
(?<名前>正規表現)
という構文で、キャプチャに名前を付けることもできます。
let text = "現在の時刻は18時30分です。"
let regex = /(?<hour>\d+)時(?<minute>\d+)分/
if let match = text.firstMatch(of: regex) {
match.0 == "18時30分"
match.hour == "18"
match.minute == "30"
}
文字列から変換
文字列で生成すると、構文チェックが実行時に行われるので try
が必要になります。また、キャプチャをするならRegexの Output
の型もわざわざ書く必要があるので面倒です。
「ユーザーが入力した正規表現で検索する」といった場面であれば使えそうです。
let text = "現在の時刻は18時30分です。"
let string = #"(?<hour>\d+)時(?<minute>\d+)分"#
let regex = try! Regex(string, as: (Substring, hour: Substring, minute: Substring).self)
if let match = text.firstMatch(of: regex) {
match.0 == "18時30分"
match.hour == "18"
match.minute == "30"
}
Regex Builder
Regex Builderは、可読性を重視して作られた、独自の正規表現の記述方法です。正規表現の構文は複雑なので、大きくなると保守が難しくなってしまうという欠点を克服します。
Xcode上で、リテラルで書いた正規表現を右クリックし、Refactor > Convert to Regex Builder を押下すると、Regex Builder を使った書き方に変換できます。
import RegexBuilder
let text = "現在の時刻は18時30分です。"
let hour = Reference(Substring.self)
let minute = Reference(Substring.self)
let regex = Regex {
Capture(as: hour) {
OneOrMore(.digit)
}
"時"
Capture(as: minute) {
OneOrMore(.digit)
}
"分"
}
if let match = text.firstMatch(of: regex) {
match.0 == "18時30分"
match[hour] == "18"
match[minute] == "30"
}
見ての通り、かなり冗長なので、簡単な正規表現であればリテラルで済ましたほうがスッキリするでしょう。
ちなみに、このブロックの中にはリテラルの正規表現を書くこともできるので、自由に併用もできます。
let regex = Regex {
Capture(as: hour) {
OneOrMore {
/\d/
}
}
/時\d+分/
}
まとめ
どの方法にも利点・欠点があることが分かりました。目的に応じて選ぶのが大切そうです。
参考