*usr_27.txt* For Vim version 6.0. Last change: 2001 Sep 03 日本語訳:2002/05/27 清水 俊彦 VIM USER MANUAL - by Bram Moolenaar 検索コマンドと正規表現 3章では、簡単な検索コマンドとパターンの指定方法について|03.9|節で述べまし た。vimにはそこで述べたよりはるかに複雑な検索ができます。この章ではよく使わ れる検索パターンについて説明します。詳細な仕様については|pattern|をご覧くだ さい。 |27.1| 大文字/小文字を無視 |27.2| ファイル終端に達した時のラップ処理 |27.3| オフセット |27.4| 複数回の一致 |27.5| 複数条件の並記 |27.6| 文字範囲 |27.7| 文字クラス |27.8| 改行記号に一致 |27.9| 例 Next chapter: |usr_28.txt| フォールド(折り畳み) Previous chapter: |usr_26.txt| 繰り返し Table of contents: |usr_toc.txt| ============================================================================== *27.1* 大文字/小文字の無視 デフォルトでは、vimの検索は大文字/小文字を区別します。ですから、"include"と "INCLUDE"と"Include"は3つの違った単語ですので、検索してもどれか一つとしか一 致しません。 では'ignorecase'オプションをonにしてみましょう。 > :set ignorecase もう一度、"include"で検索すると、"Include"にも"INCLUDE"にも"InClUDe"にもヒッ トします。('hlsearch'オプションをonにしておくと、パターンに一致した個所がす ぐに解ります。) もう一度、これをoffにしてみましょう。 > :set noignorecase これを設定したままで"INCLUDE"を索してみます。すると"include"の場合と全く同じ 個所に一致します。では'smartcase'オプションをonにしましょう。 > :set ignorecase smartcase この指定だと、パターンに1つでも大文字がある時だけ、大文字/小文字を区別しま す。これは、大文字/小文字を区別したい時で入力が必要にならない限り、大文字を 入力することはないだろうというアイデアに基づいています。そう、狡猾ですよね! この2つのオプションを設定しておくと次のようにヒットします。 > パターン ヒット ~ word word, Word, WORD, WoRd, etc. Word Word WORD WORD WoRd WoRd パターンでの大文字/小文字 -------------------------- ある特定のパターンの時だけ大文字/小文字を無視したい場合は、文字列の前に"\c" を置けばできます。"\C"は逆にパターンの大文字/小文字を区別します。 このルールは'ignorecase'と'smartcase'オプションの設定より優先します。"\c"や "\C"を用いた場合は上のオプション値は無視します。 パターン ヒット ~ \Cword word \CWord Word \cword word, Word, WORD, WoRd, etc. \cWord word, Word, WORD, WoRd, etc. "\c"や"\C"を使う大きな利点はパターンに張りついていることにあります。つまり、 検索の履歴からパターンを再利用する時には、'ignorecase'や'smartcase'を変更し ているかどうかに関わらず、常に同じ結果となるわけです。 Note: 検索パターンでの"\"アイテムの利用は'magic'オプションに依存します。 'magic'はonであることが標準的かつ推奨された設定ですので、この章では onを前提としています。変更している場合は多くの検索パターンで突然うま く動かなくなるでしょう。 Note: 思っているよりも検索に時間がかかる場合はUnixならCTRL-Cで、MS-DOSや MS-WindowsではCTRL-Breakを押してください。 ============================================================================== *27.2* ファイル終端に達した時のラップ処理 デフォルトでは前方検索は現在のカーソル位置から指定の文字列を検索し始めます。 するとそのうちにファイルの末尾まで到達します。その時に文字列が見つからかった 場合、カーソル位置をファイルの先頭に戻して最初から検索を再開します。 "n"コマンドを繰り返して次々と文字列を探していると、結局は最初にヒットした場 所に戻ってくるということを覚えておいてください。これに気が付かないと永遠に検 索を続けることになります。ちょっとでも気付き易いように、vimはこのようなメッセ ージを表示します。 search hit BOTTOM, continuing at TOP ~ "?"コマンドを使って、逆方向に検索している場合は、このメッセージとなります。 search hit TOP, continuing at BOTTOM ~ それでも最初に戻った時に気付かない場合もあります。これに気付かせる方法の1つ に'ruler'オプションをonにするというのがあります。 > :set ruler vimはウィンドウの右下隅(ウィンドウが1つの時はステータス行)に現在のカーソル 位置を表示します。このように見えます。 101,29 84% ~ 最初の数字はカーソルのある行番号です。検索の開始前にこの行番号を覚えておきま しょう。再びこの場所に戻ってきたら一周したことが確認できます。 ラップ停止 ---------- 検索時にラップしないようにするには、このコマンドを使います。 > :set nowrapscan この場合、検索の結果ファイルの末尾に達した時は次のエラーメッセージを表示しま す。 E385: search hit BOTTOM without match for: forever ~ ですから、"gg"でファイルの先頭に移動してから上のメッセージが出るまで検索をし 続ければ、一致する全個所を探せることになります。 なお、"?"を使って逆方向に検索する場合は、このエラーメッセージとなります。 E384: search hit TOP without match for: forever ~ ============================================================================== *27.3* オフセット デフォルトでは検索コマンドの実行後カーソルを該当のパターンの先頭に動きます。 オフセットを指定することでそのカーソル位置を他の場所に変更することができま す。前方検索コマンド"/"であれば、パターンの後に"/"と続けてオフセット値を指定 します。 > /default/2 上の例では"default"というパターンを検索し、見つかったパターンの2つ後ろの行 の先頭に移動します。このコマンドを今お読みのこの段落で実行すると、最初の行に "default"がありますから、2行下のオフセット位置(つまりこの行)に移動します。 オフセット値が数値であれば、カーソルを検索結果位置から指定の行の先頭までカー ソルを動かします。オフセット値には負の数も指定できます。正の数ならカーソルを その数だけ下に動かし、負の数なら上に動かします。 文字オフセット -------------- "e"は一致パターンの末尾を示すオフセット指定です。カーソルを一致したパターン の最後の文字に移動します。次のコマンドなら、"count"の最後の"t"にカーソルを動 かします。 > /const/e さらに、数値でそこから何文字前に進めるかの指定を加えられます。 このコマンドならば、一致した単語の直後にカーソルを動かします。 > /const/e+1 正の数の場合はカーソルが右に動き、負の数の場合は左に動きます。次の例の場合だ とカーソルは"const"の"s"に移動します。 > /const/e-1 オフセットが"b"で始まる場合は、カーソルはパターンの先頭に移動します。これは 単体ではあまり使い道がありません。というのは"b"を指定しなくても同じ結果にな るからです。この指定が役に立つのは後に数値指定を伴う場合です。こうすれば指定 の数だけカーソルを前後に動かすことができます。例をあげましょう。 > /const/b+2 これはヒットした文字列の先頭から2文字右にカーソルを動かします。つまり"n"の 位置に来るわけです。 繰り返し -------- 直前の検索で使ったパターンを繰り返す時にオフセット値を変更したい場合は、パ ターン指定を省略します。 > /that //e これは次の指定と同じ意味です。 > /that/e 同じオフセットを使って繰り返す時はこうです。 > / "n"でも同じことです。直前のオフセット指定を取り消すにはこうします。 > // 後方(逆方向)検索 ---------------- "?"コマンドでも同じようにオフセット指定ができます。ただしこの場合はパターン とオフセット指定の間には"/"ではなく"?"を使います。 > ?const?e-2 "b"と"e"の意味は変わりません。つまり"?"を使う場合でも逆の意味になったりしま せん。 検索開始位置 ------------ 検索を始める時、通常は現在のカーソル位置から始めます。行オフセットを指定する と問題となる可能性があります。例を示します。 > /const/-2 上の指定は"const"という単語を探し、その2行上にカーソルを動かします。次に"n" で検索を繰り返すと、その時のカーソル位置から検索を行いますので、直前に見つけ たのと同じ"const"を見つけることになり、さらにそこから2行上にカーソルを動か すと、結局元と同じ場所に戻ってしまいますので、困ってしまうでしょう。 もっとマズい場合もあります。例えば、現在行の次に"const"というパターンがある 場合、検索コマンドは次の行にパターンがあるのを見つけ、そこから2行上にカーソ ルを動かします。ということはカーソルが逆方向に進むことになるのです! 文字オフセットを指定する時はvimがそうならないように計らいます。つまり検索を 始める時に数文字分前か後ろから始めるようにするので、同じものが2度ヒットする ことはありません。 ============================================================================== *27.4* 複数回の一致 "*"は、その直前にあるアイテムの任意回の繰り返しの意味となります。 > /a* 上の例なら、"a"や"aa"や"aaa"のどれでも一致します。さらにいうと""(空文字列)に も一致します。というのは0回というのも「任意回」の一種だからです。 "*"の機能は直前にある項目に対してのみ有効です。つまり"ab*"にヒットするのは、 "a" や "ab", "abb", "abbb" などです。文字列全体の繰り返しに一致させるには、 1つの項目にグループ化しなければなりません。これには文字列の前に"\("を、後に "\)"を置きます。ですから、こういうコマンドになります。 > /\(ab\)* 上は"ab"や"abab"、"ababab"などに一致します。""にも一致します。 空文字列に一致するのを避けるには"\+"を使います。これだと直前の項目が1回以上 繰り返している時にだけ一致します。 > /ab\+ 上は"ab"や"abab"、"ababab"などに一致します。ですが、"b"が続いていない"a"には ヒットしません。 あってもなくても良い場合には"\="を使います。例えば次の例は"folder"にもヒット し、"folders"にもヒットします。 > /folders\= カウンタの指定 -------------- ある項目が指定の回数現れた時だけ一致させるには、"\{n,m}"を使います。"n"と"m" には数値が入ります。これの直前に書いてある項目が"n"〜"m"回続いた場合にヒット します。例えば、この例では"abbb"や"abbbb"、"abbbbb"にヒットします。 > /ab\{3,5} "n"を省略した場合は、"n"はデフォルトの0となります。"m"が省略された場合は、 デフォルトの「無限」になります。",m"を省略すると丁度"n"回の時だけヒットしま す。 pattern match count ~ \{,4} 0, 1, 2, 3 or 4 \{3,} 3, 4, 5, etc. \{0,1} 0 or 1, same as \= \{0,} 0 or more, same as * \{1,} 1 or more, same as \+ \{3} 3 最小一致原則 ------------ ある項目がとてもたくさんの文字にヒットするような場合があります。一致を可能な 限り小さくするには"\{-n,m}"を使います。これは"\{n,m}"と同じ意味ですが、最小 値(minimal amount possible)を使っている点が違います。これはこのように使いま す。 > /ab\{-1,3} 上は"abbb"のうちの"ab"だけにヒットします。この場合、1つ以上の"b"には絶対に 一致しません。というのはそれ以上一致させる理由がないからです。最小値よりも 多い文字に強制的にヒットさせるには何か他の方法が必要です。 "n"や"m"がない場合も同じルールが適用されます。両方の数字を取り除いて、"\{-}" とすることも可能です。これはその直前の項目が0回かそれ以上繰り返されていて、 可能な限り少ないパターンにヒットします。項目自身は常に0回にヒットします。 これは他の何かと組み合せる場合に便利です。例えば、 > /a.\{-}b これは"axbxb"の中の"axb"にヒットします。次のパターンも考えてみましょう。 > /a.*b これですと可能な限り多くの文字にヒットさせようとしますから、"axbxb"の全部が ヒットしてしまいます。 ============================================================================== *27.5* 選択肢 パターンの中での"\|"は「又は」の意味です。例をあげましょう。 > /foo\|bar これは"foo"か"bar"のどちらかにヒットします。さらに別条件を続けることもできま す。 > /one\|two\|three これは"one"か"two"か"three"にヒットします。 複数回にヒットさせるにはその全体を"\("と"\)"で囲みます。 > /\(foo\|bar\)\+ 上のパターンは"foo"や"foobar"、"foofoo"、"barfoobar"といったパターンにヒット します。もう一つの例です。 > /end\(if\|while\|for\) これは"endif"や"endwhile"、"endfor"といったパターンにヒットします。 これと同じような項目に"\&"があります。これは両方の条件が同じ文字列について両 立しなければヒットしません。最終的なヒット範囲は最後の条件に会うものを使いま す。 > /forever\&... これは"forever"のうちの"for"にヒットしますが、例えば "fortuin"にはヒットしま せん。 ============================================================================== *27.6* 文字範囲 "a"、"b"、"c"のどれかにヒットさせるには"/a\|b\|c"と書くことができます。です がこれだと"a"〜"z"のどれかにヒットさせたい時に書くの大変です。で、もっと簡単 な方法があります。 > /[a-z] [ ]はどれか1文字にヒットさせる時に使います。[ と ] の中にヒットさせたい文字 を列記します。文字リストを含めることもできます。例をあげましょう。 > /[0123456789abcdef] 上はこの中に入っている文字のどの文字にでもヒットします。マイナス記号を使うと 連続した文字範囲も指定できます。"0-3"は"0123"の意味ですし、"w-z"なら"wxyz"の 意味です。つまり次の指定は上に書いた例と同じ意味の短縮形なのです。 > /[0-9a-f] "-"の文字そのものをパターンに含めたい場合は[ ]の中の最初か最後に書きます。 次のような特殊な文字については[]の中で簡単に使えるようにしてあります。(実際 には検索パターンのどこででも使えます) \e \t \r \b この他にも[]中で使える特殊文字がいくつかあります。その全ての説明は|/[]|をご 覧ください。 smz 翻訳できず。COMPLIMENTED RANGE -> ほめられた範囲? ???な範囲 指定の文字以外にヒットさせるには、"^"を範囲の最初に指定します。これを指定す ると[]の中に指定されている文字以外の全てにヒットします。例をあげましょう。 > /"[^"]*" < " ダブルクオートの文字 [^"] ダブルクオート以外の文字なら何でもOK * 上が続く数だけ " ダブルクオートの文字 上のパターンには"foo"とか"3!x"といった文字列が(ダブルクオートを含む)ヒットし ます。 PREDEFINED RANGES 定義済みの範囲 ある種の範囲は特によく使います。vimではあらかじめ定義済の範囲を用意していま す。例えば、これは任意のアルファベットの意味になります。 > /\a これは"/[a-zA-Z]"という指定と同じ意味になります。他にもいくつか定義済のもの があります。 item matches equivalent ~ \d 数字 [0-9] \D 数字以外 [^0-9] \x 16進数の数字 [0-9a-fA-F] \X 16進数の数字以外 [^0-9a-fA-F] \s 空白文字 [ ] () \S 空白文字以外 [^ ] (以外) \l 小文字アルファベット [a-z] \L 小文字アルファベット以外 [^a-z] \u 大文字アルファベット [A-Z] \U 大文字アルファベット以外 [^A-Z] Note: 定義済の範囲を使う方が同じ意味の範囲を記述するよりずっと早いです。 上の項目を使う時は[]の中には入れません。"[\d\l]"と書いても、それは数 字か小文字という意味にはなりません。この場合なら"(\(\d\l\)"と書いて ください。 定義済の範囲の全リストは|/\s|をご覧ください。 ============================================================================== *27.7* 文字クラス 文字範囲はある特定の文字の組み合せにヒットします。文字クラスも似ていますが、 根本的な違いがあります。文字クラスでは検索パターンを変更せずに文字の組み合せ を再定義できるのです。 例えば、次のパターンで検索をするとします。 > /\f\+ "\f"というのはファイル名に使われる文字という意味です。ですから、これはファイ ル名に使える文字集合にヒットします。 ファイル名にどんな文字が使えるかは、お使いのシステムに依存します。MS-Windows ならバックスラッシュを含みますが、Unixでは含みません。これは'isfname'オプショ ンで指定します。Unixでのデフォルト値はこうです。 > :set isfname isfname=@,48-57,/,.,-,_,+,,,#,$,%,~,= 他のシステムではデフォルト値が変わります。ですから"\f"を使えば、使っているシ ステムで使えるファイル名にヒットするような検索パターンを作ることができるわけ です。 Note: 実際にはUnixではファイル名には空白文字を含むどんな文字でも使えます。 ですから、'isfname'にこういった文字を含むことは理屈の上では正しいこ とです。しかしそれだと文章の中からファイル名の終わりを見つけることが できなくなります。なので'isfname'では妥協したデフォルト値となってい るのです。 文字クラスには次のようなものがあります。 item matches option ~ \i 識別子に使える文字 'isident' \I \iから数字を抜いたもの \k キーワードとなる文字 'iskeyword' \K \kから数字を抜いたもの \p 印刷可能文字 'isprint' \P \pから数字を抜いたもの \f ファイル名に使える文字 'isfname' \F \fから数字を抜いたもの ============================================================================== *27.8* 行末との一致 vimでは改行を含んだパターンを検索することができます。今までに述べたパターン ではどれも改行に一致しないので、自分でどこに改行が来るかを指定する必要があり ます。 改行のある場所を指定するには、"\n"を使います。 > /the\nword これは行末が"the"で終わって、次の行の先頭が"word"となっている行にヒットしま す。"the word"の場合もヒットするためには、改行か空白かのどちらでもヒットする ような指定が必要です。これを行うには"\_s"を使います。 > /the\_sword 空白がいくつも続く場合も含むならこうします。 > /the\_s\+word この場合は行末が"the "で終わって、次の行の先頭が" word"であってもヒットし ます。 "\s"は空白文字の意味で、"\_s"は空白か改行の意味です。 同じように"\a"はアルファベット文字で、"\_a"はアルファベット文字か改行にヒッ トします。これ以外の文字クラスや定義済範囲の場合も"_"を間に挟むことで改行文 字を含む意味となります。 他にも多くのアイテムの最初に"\_"を付けると改行文字にヒットさせることができま す。例えば、"\_."というのは改行を含む任意の文字にヒットします。 Note: "\_.*"というパターンはファイルの末尾までの全てにヒットします。このよ うなパターンを使うと検索コマンドがとても遅くなりますので注意してくだ さい。 他にも"\_[]"というパターンを使えば改行を含んだ文字範囲の指定ができるようにな ります。 > /"\_[^"]*" これはダブルクオートで囲まれた複数の行にまたがるパターンを探すことができます。 ============================================================================== *27.9* 例題 ここでは便利そうな検索パターンをいくつか示します。今までに説明した項目をどの ように組み合せられるかを示しています。 カリフォルニア州のナンバープレートを探す ---------------------------------------- 例で使うナンバープレートは"1MGU103"だとします。これは先頭が数字、次の3桁が アルファベット、さらに3桁の数字となっています。機械的にパターンに置き換える とこうなります。 > /\d\u\u\u\d\d\d 3桁の数字と文字と考えると次のような方法も使えます。 > /\d\u\{3}\d\{3} また、[]指定を使うとこうなります。 > /[0-9][A-Z]\{3}[0-9]\{3} さて、あなたならどれを使いますか?どれでも覚えやすいのを使ってください。一番 覚えやすい方法を使う方がそうでないのを頑張って覚えるよりずっと早いですから。 もし全部覚えられるのなら、最後の1つは使わないようにしましょう。最後のは入力 する文字も多いし、実行も遅いからです。 識別子を見つける C(や多くの他言語の)プログラムでは、識別子は英文字で始まってその後に英数字が 続きます。アンダースコア(_)も使えることでしょう。こういったパターンは次のよ うに指定できます。 > /\<\h\w*\> "\<"と"\>"は単語全体が一致しているものを探すのに使います。"\h"は"[A-Za-z_]" の意味で"\w"は"[0-9A-Za-z_]".の意味です。 Note: "\<"と"\>" は'iskeyword'オプションによります。例えば、"-"を含んでい れば、"ident-"はヒットしません。この場合は次のようにします。 > /\w\@