💡

正規表現の先読み・後読みを勘違いしていた話

に公開

前提

正規表現には先読み・後読みという機能がある。
先読みは例えば以下のようなもので、これは「任意の一文字、ただし直後がaであるもの」にマッチする。

.(?=a)

後読みは例えば以下のようなもので、これは「任意の一文字、ただし直前がaであるもの」にマッチする。

(?<=a).

このような使い方だけを知っていると、「先読みは、その左側にマッチさせたい本命を置いて使うものだ」「後読みは、その右側にマッチさせたい本命を置いて使うものだ」と勘違いしかねない。少なくとも自分はしていた。そうなると以下のような正規表現が理解できなくなる。

(?=a).

本題

先読みは、「その先にある文字列が条件を満たすことを、その文字列を消費することなく確認する」と理解すべきである。例えば先ほどの正規表現(?=a).は、

  1. 文字列中のある位置にカーソルを置く
  2. 次の文字がaであることを確認する
    1. の位置にカーソルを戻し、次の任意の一文字を読む

という処理と同等のことを行う。したがって正規表現(?=a).は単にaと書くのと同等である。

後読みも同様で、「その直前にある文字列が条件を満たしていたことを、遡って確認する」と理解すべきである。例えば正規表現...(?<=a)は「任意の三文字を読み、その最後の文字がaであったことを遡って確認する」というものであり、単に..aと書くのと同等である。

最後に

このように理解してみると、英語のlookahead/lookbehindという呼称は至言であることに気付かされる。

Discussion