vimのパターン検索と置換で知っておくべきこと

提供: neovim/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
  • 賢い 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のパターンでは、違和感を感じやすいと思います。

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と/の違い
項目 / 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/

ビジュアルモードと置換

ビジュアルモードで選択している範囲だけ置換することができます。

  1. ビジュアルモードで範囲を選択する
  2.  :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 でビジュアルモードで選択した文字列を検索できる

関連項目




スポンサーリンク