正規表現の先読みは (?=) 、後読みは (?<=) と書きます。 また、否定先読みは (?!) 、否定後読みは (?<!) と書きます。
(?=) 先読み
正規表現における先読みは、現在の読み込み位置を動かさず、文字列を消費しないで、次に出現する文字列を先に見てマッチするか確認できる仕組みです。 例えば、メールアドレスの形式にマッチする場合に、そのユーザ名の部分だけを抽出したい場合は、以下のような正規表現となります。
[-a-zA-Z0-9_.]+(?=@example.com)
(?!) 否定先読み
正規表現における否定先読みは、現在の読み込み位置を動かさず、文字列を消費しないで、次に出現する文字列を先に見てマッチしないことを確認できる仕組みです。 例えば、"book" にはマッチするけど、"bookshelf" だけはマッチさせないような正規表現を書くと次のようになります。
book(?!shelf)
(?<=) 後読み
正規表現における後読みは、現在の読み込み位置を動かさず、前に出現した文字列を再度見てマッチするか確認できる仕組みです。 例えば、人の名前としてマッチしたアルファベットの文字列の前に "Dr. " (先生) という文字列があるときだけマッチさせるには、以下のような正規表現となります。
(?<=Dr\. )([A-Z][a-z]+)
(?<!) 否定後読み
正規表現における否定後読みは、現在の読み込み位置を動かさず、前に出現した文字列を再度見てマッチしないことを確認できる仕組みです。 例えば、調べたいメソッド名が「#」でコメントアウトされていないときのみマッチさせたい場合は、以下のような正規表現になります。
(?<!#)method_name\(\)