正規表現グループ

() によるキャプチャグループと後方参照。パターンの一部をグループ化し、マッチした部分を取得・再利用する。

正規表現グループ (Group) は、パターンの一部を括弧 () で囲んでグループ化する機能です。グループ化には 3 つの主要な種類があります。キャプチャグループ (...)、名前付きキャプチャグループ (?<name>...)、非キャプチャグループ (?:...) です。それぞれ用途が異なり、適切に使い分けることで正規表現の可読性とパフォーマンスが向上します。

キャプチャグループはマッチした部分文字列を記憶し、後方参照や置換で再利用できます。JavaScript では match()exec() の結果配列でキャプチャグループの値を取得できます。たとえば /(\d{4})-(\d{2})-(\d{2})/ で日付文字列をマッチさせると、年・月・日をそれぞれ個別に取得できます。

落とし穴として、グループに量指定子を付けても繰り返した回数分が残るわけではありません。/(\w)+/ を「abc」に当てると全体は「abc」にマッチしますが、1 番のグループに残るのは最後の 1 回分の「c」だけです。繰り返しの各回を取り出したい場合は、グループの外側を繰り返すのではなく matchAll() で 1 件ずつ回します。

名前付きグループ (?<name>...) を使うと、groups.name でアクセスでき可読性が大幅に向上します。/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/ のように記述すれば、result.groups.year で年を取得でき、番号による参照よりも意図が明確です。

非キャプチャグループ (?:...) はグループ化のみを行い、マッチ結果を記憶しません。実用上の利点は速度よりも、グループ番号を消費しないことです。キャプチャグループを途中に 1 つ挿入すると以降の番号がすべてずれ、$1\1 による参照が壊れますが、非キャプチャグループなら番号に影響しません。速度差は Node.js 26 の実測で 2,000 文字の入力に 20,000 回照合して 10 ミリ秒程度と、通常の用途で体感できる差にはなりません。たとえば (?:http|https):// は URL のプロトコル部分をグループ化しますが、キャプチャは行いません (この例なら https?:// とも書けます)。

後方参照 \1\2 を使うと、同じパターン内で以前にキャプチャした文字列と同じ文字列にマッチさせることができます。重複単語の検出 (\w+)\s+\1 が代表例です。よく引かれる HTML タグの対応検証 <(\w+)>.*?</\1> は、入れ子があると内側の終了タグで打ち切られ、大文字小文字が違うだけでも不一致になるため、タグの対応確認には使えません。置換操作では $1$2 でキャプチャグループの内容を参照し、テキストの再構成が可能です。

文字数カウントとの関連では、グループを使ってテキストから特定のパターンを抽出し、その出現回数や文字数を集計する用途があります。たとえば URL やメールアドレスをグループでキャプチャし、本文中に含まれる数を数えるといった分析が可能です。

この記事を共有