正規表現 - 選択と分岐
1、選択とは (Alternation)
選択(Alternation)とは、正規表現で||記号を使用して「または」の論理関係を表すことです。複数の可能なパターンのいずれかにマッチさせることができます。
cat|dog
このパターンは "cat" または "dog" にマッチします。
2、分岐とは (Branching)
分岐とは、正規表現エンジンがマッチング中に選択点に遭遇したとき、異なるマッチング経路を試行することを指します。ある経路のマッチングが失敗した場合、エンジンはバックトラックして他の可能な経路を試します。
原理の解説
選択演算子|の動作原理
- 正規表現エンジンは左から右にスキャンし
||で区切られた各選択肢を - 最初の選択肢のマッチングを試み、成功したら停止します
- 最初の選択肢がマッチしない場合は、2番目の選択肢を試します
- 同様に、マッチが見つかるか、すべての選択肢を試し終えるまで続けます
グループ化と選択
選択は通常、グループ化()と組み合わせて使用し、選択の範囲を限定します:
例
gr(a|e)y
このパターンは "gray" または "grey" にマッチします。
分岐のバックトラッキングメカニズム
正規表現エンジンが選択点に遭遇したとき:
- 現在位置を記憶する(チェックポイントを作成)
- 最初の分岐を試す
- 失敗した場合、チェックポイントに戻る
- 次の分岐を試す
- 成功するか、すべての分岐を試し終えるまで繰り返す
実践例
基本的な選択の例
例
// 複数の日付形式にマッチ
const datePattern = /\b(January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}\b/;
console.log(datePattern.test("March 15, 2023")); // true
console.log(datePattern.test("Sept 10, 2022")); // false (省略形はマッチしない)
const datePattern = /\b(January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}\b/;
console.log(datePattern.test("March 15, 2023")); // true
console.log(datePattern.test("Sept 10, 2022")); // false (省略形はマッチしない)
グループ化による選択の例
例
import re
# アメリカ式またはイギリス式の綴りにマッチ
pattern = r"colou?r|color"
text = "The color is red and the colour is blue"
matches = re.findall(pattern, text)
print(matches) # 出力: ['color', 'colour']
# アメリカ式またはイギリス式の綴りにマッチ
pattern = r"colou?r|color"
text = "The color is red and the colour is blue"
matches = re.findall(pattern, text)
print(matches) # 出力: ['color', 'colour']
複雑な分岐の例
例
// 複数の電話番号形式にマッチ
String phonePattern = "(\\(\\d{3}\\) ?|\\d{3}[-.]?)\\d{3}[-.]?\\d{4}";
String[] testNumbers = {
"(123)456-7890",
"123.456.7890",
"123-456-7890",
"1234567890"
};
for (String number : testNumbers) {
System.out.println(number.matches(phonePattern)); // すべて true を出力
}
String phonePattern = "(\\(\\d{3}\\) ?|\\d{3}[-.]?)\\d{3}[-.]?\\d{4}";
String[] testNumbers = {
"(123)456-7890",
"123.456.7890",
"123-456-7890",
"1234567890"
};
for (String number : testNumbers) {
System.out.println(number.matches(phonePattern)); // すべて true を出力
}
応用
パフォーマンス最適化のヒント
高頻度の選択肢を先頭に置く:最もマッチする可能性の高い選択肢を前に置きます
(common|uncommon|rare) # 优化顺序
冗長な分岐を避ける:
(a|ab|c) # 不好 (ab?|c) # 更好
非キャプチャグループを使用する:グループをキャプチャする必要がない場合
(?:pattern1|pattern2)
実際の使用例
- ログ分析:複数のエラーメッセージ形式にマッチ
- フォーム検証:複数の有効な入力形式を受け付ける
- テキスト処理:同義語や異なる綴りを検索する
- ルーティングマッチング:WebフレームワークのURLルーティング