正規表現先読み
(?=...) や (?!...) で後続パターンを条件にマッチさせる正規表現の構文。文字列を消費せずに条件を検査する。
正規表現の先読み (lookahead) は、特定のパターンが後続するかどうかを条件にマッチを判定する構文です。肯定先読み (?=...) は指定パターンが続く場合にマッチし、否定先読み (?!...) は続かない場合にマッチします。先読みはゼロ幅アサーション (zero-width assertion) と呼ばれ、マッチ位置を進めずに条件だけを検査する点が通常のパターンと異なります。
先読みの基本的な動作を具体例で説明します。\d+(?=円) は「100円」の「100」にマッチしますが、「円」自体はマッチ結果に含まれません。これは先読みが文字列を「消費」しないためです。否定先読みの例として、\d+(?!円) は「100ドル」の「100」にはマッチしますが、「100円」の「100」にはマッチしません。正規表現入門の書籍で先読みの基礎を学べます。
先読みの最も実用的な活用例はパスワード検証です。複数の先読みを組み合わせることで、「英字を含む」「数字を含む」「特殊文字を含む」「8 文字以上」などの条件を 1 つの正規表現で同時にチェックできます。たとえば ^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$ は、これらすべての条件を満たすパスワードにマッチします。
JavaScript では ES2018 から後読み (lookbehind) もサポートされています。肯定後読み (?<=...) は指定パターンが前方にある場合にマッチし、否定後読み (?<!...) は前方にない場合にマッチします。たとえば (?<=\$)\d+ は「$100」の「100」にマッチしますが、「100」単体にはマッチしません。
先読みと後読みを組み合わせると、特定の文脈にある文字列だけを精密に抽出できます。ただし、後読みは一部のブラウザや正規表現エンジンでサポートされていない場合があるため、対象環境の互換性を確認することが重要です。また、複雑な先読みパターンはバックトラッキングの増加によりパフォーマンスに影響する可能性があります。正規表現実践の書籍で高度なパターンを習得できます。
文字数カウントとの関連では、先読みを使って特定の条件を満たす文字列の位置を特定し、テキストの構造分析に活用できます。たとえば数値の 3 桁区切り表示 (\d(?=(\d{3})+$)) は、先読みの実用的な応用例の一つです。