言明
言明 (assertion) とは、カレントのマッチング位置の直前・直後の文字に対する
テストであり、文字を消費 (consume)〔つまり文字自体にマッチ〕しません。
単純な言明コード \b, \B, \A, \Z, \z, ^ および $ については、
エスケープシーケンス で説明しました。より複雑な言明は、サブパターンを用いて記述します
〔言明サブパターン (assertion subpattern) と呼ばれる〕。
言明サブパターンには、2 種類あります。対象文字列において
カレントの位置の先を読むものと、後ろを読むものです。
言明サブパターンは、カレントのマッチング位置を変更しないことを除き、
通常と同じようにマッチングが行われます。先読み言明 (lookahead assertion) は、
肯定の言明 (positive assertion) の場合 (?= で始まり、
否定の言明 (negative assertion) の場合 (?! で始まります。例えば、
\w+(?=;)
は、セミコロンが後に続く単語にマッチしますが、
マッチ対象それ自体にはセミコロンは含まれません。また、
foo(?!bar)
は、"bar" が後ろに続かない "foo" にマッチします。
なお、一見、良く似たパターンですが
(?!foo)bar
は、"foo" 以外のものの後にある "bar" を見つけるものではないことに
注意してください。これは、どこにある "bar" とでもマッチしてしまいます。
続く 3 文字が "bar" である場合、 (?!foo) は常に真となってしまうからです。
このような探索を実現するためには、戻り読み言明 (lookbehind assertion)
が必要です。
戻り読み言明は、肯定の言明の場合 (?<= で始まり、
否定の言明の場合 (?<! で始まります。例えば、
(?<!foo)bar
は、"foo" 以外の後にある "bar" の存在を見つけるものです。
戻り読み言明内のパターンは、それがマッチし得る文字列の長さが
固定でなければなりません〔繰り返しを指定できません〕。ただし、
選択肢を用いた場合、各選択肢は〔固定長でなければいけませんが〕
すべて同じ長さである必要はありません。つまり、
(?<=bullock|donkey)
とはできますが、
(?<!dogs?|cats?)
は、コンパイル時にエラーになります。
戻り読み言明の最上位においてのみ、異なる長さの文字列にマッチするような
選択肢が使用可能です。Perl 5.005 においては、すべての選択肢が
同じ長さの文字列にマッチする必要があります。つまり、この機能は
PCRE の拡張モジュールです。
(?<=ab(c|de))
という戻り読み言明は、最上位にひとつの選択肢しかなく、
その選択肢は異なる長さの文字列にマッチしうるので、不正です。
しかし、
(?<=abc|abde)
のように、最上位において選択肢を 2 つ用いるように
書き換えると使用可能です。
後方言明の実装においては、選択肢ことに一時的に固定の幅だけ
カレントの位置を後退させ、マッチを試みます。カレントの位置の前に
十分な文字がない場合は、マッチは失敗とみなされます。
再試行無しのサブパターンと組み合わせた戻り読み言明は、
文字列の終端でのマッチングに特に有用です。
再試行無しのサブパターンについてのセクションの最後にて例を示します。
(任意の種類の)複数の言明を連続して指定することも可能です。例えば、
(?<=\d{3})(?<!999)foo
は、"999" でない 3 桁の数字の後にある "foo" にマッチします。
それぞれの言明は、対象文字列の同じ場所に独立して適用されることに
注意して下さい。まず、前の 3 文字がすべて数字であることがチェックされ、
続いて、同じ 3 文字が "999" でないことが確認されます。このパターンは、
"foo" の前に 6 個の文字があり、その前半が数字で後半の 3 文字が "999"
でないというパターンにマッチするものではありません。例えば、"123abcfoo"
にはマッチしません。これを行うパターンは次のようになります。
(?<=\d{3}...)(?<!999)foo
この時、最初の言明は、先行する 6 つの文字を探し、
最初の 3 文字が数字であることを確認します。続いて、2 番目の言明は、
先行する 3 文字が "999" でないことを確認します。
言明は、自由に組み合わせてネスト可能です。例えば、
(?<=(?<!foo)bar)baz
は、"foo" 以外の後にある "bar" の後に有る "bar" があればマッチします。
一方、
(?<=\d{3}...(?<!999))foo
は、999 でない 3 桁の数字とさらに 3 文字の後に続く "foo"
にマッチするパターンです。
言明サブパターンは、キャプチャ用サブパターンではありません
〔値のキャプチャは行われません〕。繰り返しもできません。
同じことを複数回言明しても意味がないからです。
キャプチャ用サブパターンが言明の内部に含まれている場合、
言明の種類に関係なく、キャプチャ用サブパターンの番号付けにあたって
カウントされます。しかし、文字列のキャプチャは、肯定の言明に対してのみ
行われます。否定の言明の中で行っても無意味だからです。
カッコ付サブパターンによる言明は、最大 200 まで用いることができます。