Vimの正規表現における先読み、後読み

・Vimで使える正規表現の一覧
http://archiva.jp/web/tool/vim_regexps.html

・先読み、後読み
http://vim-jp.org/vim-users-jp/2009/09/20/Hack-75.html

特定のパターンが対象のパターンの後ろに来るという条件 → 先読み
特定のパターンが対象のパターンの前に来るという条件 → 後読み

肯定先読み:\@=
否定先読み:\@!
肯定後読み:\@<=
否定後読み:\@<!

Vimでは、これらのパターン指定は、直前の文字、またはグループに対して指定する。
つまり、文字列 "Hello" に対して肯定先読みを行う場合、グループ化して、

\(Hello\)\@=

と記述する。

肯定先読みと肯定後読みは、普通に正規表現を記述するのとマッチする箇所は同じだが、マッチの対象に先読み、後読みパターンを含めない点が異なる。即ち、文字列そのものをマッチするのではなく、位置をマッチするということである。

肯定先読み

肯定先読みは、patternの直前の位置にマッチする。

AAABBB

に対して、

%s /\(BBB\)\@=/CCC/

という置換を行うと、

AAACCCBBB

になる。

肯定後読み

肯定後読みは、patternの直後の位置にマッチする。

AAABBB

に対して、

%s /\(BBB\)\@<=/CCC/

という置換を行うと、

AAABBBCCC

になる。

(はてな記法で表組みを作ると、なぜかこの位置に多数のブランクが入る)

分類 対象文字列 正規表現置換 置換後の文字列
普通の正規表現 AAABBB %s /BBB/CCC/ AAACCC
肯定先読み AAABBB %s /\(BBB\)\@=/CCC/ AAACCCBBB
肯定後読み AAABBB %s /\(BBB\)\@<=/CCC/ AAABBBCCC

否定先読み、否定後読み

肯定先読み、後読みよりも、否定先読み、後読みの方が使う機会が多いかもしれない。

「特定の文字で始まらない」(否定後読み)という検索や、「特定の文字で終わらない」(否定先読み)という検索でよく使用する。


・例1:"myobj."で始まらない"method()"を"myobj.method()"に置換する

:%s /\(myobj\.\)\@<!method()/myobj.method()/g

・例2:()で終わらない"function"を消去する

:%s /function\(()\)\@!//g

全体的にVimの正規表現はバックスラッシュを多用するので読みにくい。



実のところ私は未だに、もう何年も、VimとEmacsの間で揺れている。
私の小指は「Vimにしろ」と言っている。