vimのパターン検索と置換で知っておくべきこと
vimには、強力な検索と置換の機能があります。ワンタッチでできる検索、インクリメンタルサーチ、検索履歴、正規表現、globalによるコマンド実行など多くの機能があります。これらを使いこなすことで、編集スピードを加速させることができます。ここでは、知っておくべき、いくつかのエッセンスを取り上げます。
読み方
- vimのパターン検索と置換で知っておくべきこと
- ぶいあいえむ の ぱたーん けんさく と ちかん で しっておくべきこと
目次
概要
vimには、多くの機能があります。検索と置換も強力です。vim使いとして、知っておくべき要素がいくつもあります。
vimのプラグインで、検索、置換を強化することもできます。
検索
vimには、/ (検索)とglobal(検索にも使える)があります。
- /, ?, *, #, g*, g#
- :g, :v
- vimgrep
/ での検索
次のパターンを検索する
/ や ? で検索を開始し、次のマッチするパターンを検索するには、 n や N (前) を使います。
検索の設定
- インクリメンタルサーチ
set incsearch
- ハイライトサーチ
set hlsearch
検索の履歴
- / + C-f
- 検索の履歴も編集できる
- 検索の履歴も検索できる
検索のパターン
- 正規表現でも検索できる
- /^main
- 大文字小文字を無視する
/ignorecase\c
- vimrc で設定することもできます。
set ignorecase
- vimrc で設定することもできます。
- 賢い smartcase というオプションもあります。
set smartcase
正規表現のメタ文字の扱い
vimの正規表現には、メタ文字の扱いに関して、4つのモードがあります。
- magic (デフォルト)
- very magic
- nomagic
- very nomagic
magic
/, :global, :vglobal, :subsutitute のパターン部分で正規表現が使えます。 それらのコマンドは、パターンのメタ文字の扱いのオプションを持っています。 デフォルトでは、 magic と呼ばれるオプションです。
現在のオプションを確認する方法は、以下のコマンドです。
:set magic?
vimのデフォルトのパターン検索で、正規表現を使おうとすると「エスケープ祭り」が発生します。 fooかbarを検索する場合、以下のパターンになります。
/\(foo\|bar\)
vimのmagicのパターンでは、違和感を感じやすいと思います。
エスケープの有無 | メタ文字 |
---|---|
エスケープ不要 | ., *, ^, $ |
エスケープが必要 | +, ?, (, ), &pipe; |
very magic
very magicは、Perlのような正規表現になります。
very magicに設定する「 set hoge 」 のようなオプションは存在しません。very magic を有効にするには、パターンに \v を入力します。
「エスケープ祭り」が起こした、 fooかbarを検索する場合のパターンは、以下のようにエレガントになりました。
/\v(foo|bar)
常に very magic のモードにしておきたいと思うなら、 .vimrc で map するのがよいでしょう。
:nnoremap / /\v
*と#での検索
- と#を使用することで、カーソルの単語を検索できます。
1つめのfooで検索すると2つめのfooにマッチします。
foo foo bar foobar
g*, g# なら、カーソルの単語の前後に関係なく検索ができます。 foo に対して検索するときに foobar にもマッチするという意味です。 1つめのfooで検索すると2つめ(foo)と3つめ(foobar)のfooにマッチします。
gdの検索
プログラミング言語での検索の話です。
- gd:カレントの変数のローカルの宣言を検索することができます。
- gD
- カレントの変数のグローバルの宣言を検索することができます。
:g, :global とは
「:global(:g)」 とは、一見、検索コマンドに見えますが、本当は、パターンにマッチした行に ex コマンドを実行するためのコマンドです。
:help :g
「:g」のヘルプを見てみましょう。
:g :global E147 E148 :[range]g[lobal]/{pattern}/[cmd] [range]の範囲で{pattern}にマッチする行に対して、Exコマ ンド[cmd](省略した場合 ":p")を実行する。 :[range]g[lobal]!/{pattern}/[cmd] [range]の範囲で{pattern}にマッチしない行に対して、Exコ マンド[cmd](省略した場合 ":p")を実行する。 :v :vglobal :[range]v[global]/{pattern}/[cmd] :g! と同じ。
:gの例
foo のある行を削除します。
:g/foo/d
foo のある行の hoge を meta に置換します。
:g/foo/%s/hoge/meta/g
:vglobal :v
\:v は、:g の否定です。 foo のない行を削除します。
:v/foo/d
foo のない行の hoge を meta に置換します。
:v/foo/%s/hoge/meta/g
:g norm
norm を利用すると vim のコマンドを実行できます。 echo の行を次の行と連結(j)します。
:g/^ecno/norm J
echo "hoge"; echo "bar";
vimgrep
vimgrep とは
vim内部からgrepができます。grepするために、vimを中断(C-z )する必要はありません。grepの結果をvimで閲覧し、行きたい行へジャンプできます。
カレントのファイルをgrepするなら、以下のコマンドです。
:vimgrep foo %
foo bar を検索するなら
:vimgrep /foo bar/ %
などと囲む必要があります。
マッチした行をquickfix-windowを確認するには、以下のコマンドで確認できます。
:cwindow
quickfix-window で表示されるのは、以下のような文字列です。
search.txt|7 col 1| foo bar hoge search.txt|8 col 1| foo bar hoge search.txt|9 col 2| foo bar hoge
quickfix-window を最初から開くには、 | cwin を使用します。
:vimgrep foo %|cwin
vimgrep での対称の指定
- vimgrep /pattern/ **
- カレントディレクトリ以下のすべてのファイルを対称にする(再帰的)
- vimgrep /pattern/ foo/**
- ディレクトリ foo 以下のすべてのファイルを対称にする(再帰的)
- vimgrep /pattern/ foo/*
- ディレクトリ foo 以下のファイルを対称にする
- vimgrep /pattern/ foo/**/*.c
- ディレクトリ foo 以下のファイル *.c を対称にする(再帰的)
vimgrep と/検索の違い
項目 | / | vimgrep |
---|---|---|
quickfix-window | 使えない | 使える |
ヒット件数 | わからない | わかる |
正規表現 | 使える | 使える |
次のマッチへの移動 | n | :cnext (:cn) |
前のマッチへの移動 | N | :cpreious (:cp), :cN (:cNext) |
検索対象 | カレントのバッファ | 引数で指定する |
置換
- :s, :%s
- :g/%s/
:sによる置換
カーソルのある行の置換は、
:s/foo/bar
です。行にfooが何度も出現しても、最初のfooだけが置換されます。
ファイル(バッファ)全体の置換は、
:%s/foo/bar
です。 行にfooが何度も出現しても、最初のfooだけが置換されます。 行の置換との違いは、% があるだけです。
カーソルのある行の置換で、かつ何度も置換するには、
:s/foo/bar/g
です。 g オプションを追加します。
ファイル全体も同様に g オプションをつけると、すべての行で、何度も置換されます。
:%s/foo/bar/g
置換時に確認する
置換するときに、本当にそれを置換するか、確認したい場合は、 c オプションを指定します。
:%s/foo/bar/c
gとcのオプションを両方指定する場合は、以下の通りです。
:%s/foo/bar/gc
複雑な置換条件で、目で確認しながらのほうが速い場合には、c を使うといいでしょう。
前方参照
正規表現では、前方参照が使われます。正規表現で置換することで、より置換作業を簡単に、高速にできます。 (, ) でキャプチャした文字列を \1, \2, \3 という形で参照できます。
前にfooがあって、うしろに hoge か meta がある場合に、置換する例です。
foo 123 hoge foo 456 meta foo 789 null
:%s/foo \(.*\) \(hoge\|meta\)$/\2 = \1/
hoge = 123 meta = 456 foo 789 null
このエスケープ祭りも very magic で綺麗にできます。
:%s/\vfoo (.*) (hoge|meta)$/\2 = \1/
ビジュアルモードと置換
ビジュアルモードで選択している範囲だけ置換することができます。
- ビジュアルモードで範囲を選択する
- :s/foo/bar で置換を実行する。
:'<,'>s/foo/bar
すべてのバッファで置換する
開いているバッファすべてに置換コマンドを実行する例です。 すべてのバッファを操作するには、argdoコマンドを使用します。 update をつけることで、変更した場合に、書き込み(:w)します。
:argdo %s/foo/bar/g | update
Perl/Rubyのようなの正規表現 eregex.vim
eregex.vimというプラグインでは、Perl/Rubyの正規表現で検索や置換が行えます。デメリットとして、eregex.vim では、インクリメンタルサーチができません。 very magic (/\v) があれば、eregex.vim を使わずとも、ある程度は、不便をせずにやっていけるのではないでしょうか。
ビジュアルモードと検索 vim-visualstar
ビジュアルモードで選択した文字列を検索する機能を提供するのが thinca/vim-visualstar です。
NeoBundle 'thinca/vim-visualstar'
ビジュアルモードで選択し、 */# などで検索できます。
the Silver Searcher ag.vim
grep よりも 賢いack, ackよりも高速なag(the Silver Searcher)です。 恩恵としては、vimgrepよりも高速になるだけでしょう。
NeoBundle 'vim-scripts/ag.vim'
検索のやり方は、以下の通りです。
:Ag foo
Qfreplace
Qfreplace は、 grep の結果から置換するためのプラグインです。
quickfix のウィンドウから Qfreplace を呼び出し、そのバッファを編集すると元のバッファが変更される、というものです。
NeoBundle 'thinca/vim-qfreplace'
:vimgrep foo % :cwin :Qfreplace :%s/foo/bar/ :w
まとめ
- very magic でパターン検索を簡単にできる
- vim-visualstar でビジュアルモードで選択した文字列を検索できる
関連項目
- vimの検索と置換
- vimの検索でマルチインクリメンタルハイライトを実現するincsearch.vim
- vimの矩形ビジュアルモードで矩形選択範囲内を置換する
- vimの検索のハイライトを消す方法
- vimで改行だけの空行を削除する方法
- メインページ
ツイート