[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10. 探索と置換

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Search"
"emacs/探索と置換"へのコメント(無し)

他のエディタと同様に、Emacsにも文字列を探索するコマンドがあります。 主な探索コマンドがインクリメンタル(incremental)であるという点で、 普通とは違います。 探索したい文字列全体を入力し終えなくても、探索を始めます。 他のエディタの探索コマンドのように、 インクリメンタルでない探索コマンドもあります。

指定した文字列の出現すべてを探し出して別の文字列に置換する、 普通の置換コマンドreplace-stringに加えて、 Emacsにはより高級な、 出現箇所をみつけるたびに置換するかどうか対話的に尋ねる 問い合わせ型置換コマンドquery-replaceもあります。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.1 インクリメンタルサーチ

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Incremental%20Search"
"emacs/インクリメンタルサーチ"へのコメント(無し)

インクリメンタルサーチでは、 探索文字列の最初の文字を打つとただちに探索を開始します。 探索文字列を入力するたびに、 Emacsは(それまでに入力した)文字列がどこでみつかるか表示します。 目的の箇所を特定するのに十分なだけの文字を打ってしまえば、 そこで終りにできます。 つぎに何をするかにもよりますが、 RETで探索を陽に終了する必要がある場合もあります。

C-s
前向きにインクリメンタルサーチする(isearch-forward)。
C-r
後向きにインクリメンタルサーチする(isearch-backward)。

C-sはインクリメンタルサーチを始めます。 C-sはキーボードから文字を読み取り、 打った文字が最初に現れる位置までカーソルを移動します。 たとえば、C-sに続けてFを打つと、 カーソルは最初に現れる`F'の直後に移動します。 さらにOを打つと、カーソルは最初に現れる`FO'の直後に移動します。 さらにOを打つと、探索を開始した場所以降で最初に現れる `FOO'の直後にカーソルが移動します。 各段階において、反転表示できる端末では、 探索文字列に一致するバッファ内のテキストを強調表示します。 また、各段階において、エコー領域に表示した現在の探索文字列も更新します。

探索する文字列を打ちまちがえたときには、DELで取り消せます。 DELを1回押すごとに、探索文字列の最後の文字を取り消していきます。 ただし、Emacsがつぎの入力文字を受け付け可能になるまで、 この取り消し操作は実行できません。 つまり、取り消そうと思っている文字をみつけるか、 もしくはみつけられなかったことが確定する必要があります。 それまで待てないなら、以下に説明するようにC-gを使ってください。

目的の箇所まで移動できたら、RETを打ちます。 すると、探索を終了しカーソルはその箇所に留まります。 また、探索に関係ないコマンドを打っても、 探索を終了し、そのコマンドを実行します。 したがって、C-aと打てば、探索を終了し、カーソルを行頭に移動します。 RETが必要な場面は、 つぎに入力したいコマンドが、印字文字、DELRET、および、 探索で特別な意味を持つその他の各種コントロール文字 (C-qC-wC-rC-sC-yM-yM-rM-s)である場合だけです。

`FOO'を探してそれがみつかった場合でも、 予期していた`FOO'ではないこともあるでしょう。 最初の`FOO'以降に、2つめの`FOO'があることを 忘れていたような場合です。 このようなときには、さらにC-sを打てば、 探索文字列のつぎの出現箇所に移動できます。 この操作は何度でも繰り返せます。 行き過ぎてしまったときには、DELC-sの操作を取り消せます。

探索を終了したあとでも、単にC-s C-sと打てば、 ふたたび同じ文字列を探索できます。 つまり、最初のC-sがインクリメンタルサーチを起動して、 つぎのC-sが『再探索』を意味します。

以前に探索した文字列を再利用するには、 探索リング(search ring)を使います。 コマンドM-pM-nでリング内を移動して、 再利用する文字列を取り出します。 これらのコマンドは、探索リング内の選択した要素をミニバッファに置きますから、 編集することも可能です。 C-sC-rを打てば、 文字列の編集を終了して探索を開始できます。

探している文字列がまったくみつからなかった場合には、 エコー領域に`Failing I-Search'と表示されます。 カーソルは、指定した文字列に可能な限り一致する箇所の直後にあります。 たとえば、`FOOT'を探索しようとしたのに`FOOT'がなければ、 カーソルは`FOOL'の`FOO'の直後にあります。 この時点でできることはいくつかあります。 文字列を打ちまちがえたのならば、それを消去して訂正します。 その箇所でよいのなら、『探索したものを受理する』ために、 RETか他のEmacsコマンドを打ちます。 あるいは、C-gを打てば、 探索文字列からみつけられなかった文字(`FOOT'中の`T')を取り除き、 みつけた文字列(`FOOT'中の`FOO')は そのままにしておくこともできます。 ここで、さらにC-gを打つと、 探索全体を取り止めて、探索を開始した位置に戻ります。

探索文字列に大文字を指定すると、 大文字小文字を区別(case-sensitive)して探索します。 探索文字列から大文字を削除すると、この効果は消えます。 See 節 10.6 探索と大文字小文字の区別

探索に失敗したときに、さらにC-sを打って探索の続行を指示すると、 バッファの先頭からもう一度探索し始めます。 後向きの探索に失敗したときに再度C-rを打つと、 バッファの末尾から探索を再開します。 これらの操作は巻き直し(wrapping around)と呼ばれます。 巻き直しが起こると、探索のプロンプトには`Wrapped'が表示されます。 もともとの探索開始位置を通過してなお探索を続けると、 表示が`Overwrapped'に変わります。 これは、探索文字列にすでに一度一致した箇所を 再度探索していることを意味します。

『中断』文字C-gは、探索中には特別な意味があり、 その機能は探索の状態に依存します。 指定したものがみつかり入力待ちの状態にあると、 C-gは探索全体を取り消します。 カーソルは探索開始位置に戻ります。 Emacsが探索中であったり探索に失敗したために、 探索文字列内に未発見の文字がある場合にC-gを打つと、 探索文字列から未発見の文字を消去します。 そうすると、これで探索が成功したことになるので、 入力待ちになります。 続けてC-gを打つと、探索全体を取り消します。

改行を探索するには、C-jを打ちます。 コントロールSや改行などのコントロール文字を探索するには、 まずC-qを打ってクォートする必要があります。 C-qのこの機能は、挿入時の利用法に似ています (see 節 3.1 テキストを挿入する)。 このコマンドは、あとに続く文字を、 同じ文脈における『普通の』文字と同様に扱うようにします。 文字を8進コードで指定することもできて、 C-qに続けて8進数字列を入力します。

C-rを使えば、後向き探索に変更できます。 ファイルのうしろのほうで探索し始めたために探索に失敗したのであれば、 これを試してください。 C-rを繰り返し打つと、後向きにさらに探索を続けます。 C-sは、ふたたび前向き探索を再開します。 探索中のC-rDELで取り消せます。

始めから後向きで探索するのであれば、 C-sのかわりにC-rを使って探索を始めます。 C-rは、後向きに探索するコマンドisearch-backwardを起動します。 前向き探索が開始位置よりうしろにある一致箇所をみつけるのと同様に、 後向き探索は開始位置よりまえにある一致箇所をみつけだします。

インクリメンタルサーチ中には、文字C-yC-wを使って、 バッファから探索文字列へテキストを取り込むことができます。 この機能は、ポイント位置にあるテキストの出現箇所を探すときに便利です。 C-wは、ポイント以降の単語を探索文字列の一部としてコピーし、 ポイントをその単語の末尾に進めます。 探索を繰り返す意味でC-sを打つと、 その単語を含んだ文字列を探索します。 C-yC-wに似ていますが、 現在行の残りの部分をすべて探索文字列にコピーします。 大文字小文字を区別しない探索では、 C-yC-wはともに、 コピーするテキストを小文字だけに変換します。

文字M-yは、キルリングから探索文字列にテキストをコピーします。 これには、ヤンクコマンドC-yがヤンクするのと 同じテキストを用います。 See 節 7.8 ヤンク

インクリメンタルサーチを終了すると、 探索開始前にポイントがあった位置にマークを置きます。 これにより容易にその位置に戻れます。 暫定マーク(transient-mark)モードでは、 マークが不活性のときに限って、 インクリメンタルサーチが設定するマークも不活性です。

インクリメンタルサーチ中に用いる特別な文字をカスタマイズするには、 キーマップisearch-mode-map中のバインディングを変更します。 バインディング一覧は、C-h f isearch-mode RETを使って isearch-modeに関する説明文を参照してください。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.1.1 低速端末でのインクリメンタルサーチ

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=10.1.1%20低速端末でのインクリメンタルサーチ"
"emacs/低速端末でのインクリメンタルサーチ"へのコメント(無し)

速度の遅い端末でのインクリメンタルサーチでは、 表示時間が少なくてすむように設計された表示形式を使います。 みつけた箇所でバッファを再表示するかわりに、 新たに1行分のウィンドウを作ってそこにみつけた行を表示します。 この1行分のウィンドウは、 探索することでポイントが画面に表示中のテキストから 飛び出た時点で使われます。

探索を終了すると、この1行分のウィンドウは消えます。 そして、Emacsは探索を完了したウィンドウを再表示して、 新たなポイント位置を示します。

低速向けの表示形式を使うのは、 端末のボーレートが変数search-slow-speedの値以下である場合で、 その初期値は1200です。

低速向けの表示形式に使う表示用ウィンドウの行数は、 変数search-slow-window-linesで制御します。 通常の値は1です。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.2 一括型探索

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Nonincremental%20Search"
"emacs/一括型探索"へのコメント(無し)

Emacsでは、従来方式の一括型探索コマンドもあります。 探索を開始するまえに探索文字列全体を打っておく必要があります。

C-s RET string RET
stringを探索する。
C-r RET string RET
stringを後向きに探索する。

一括型探索を実行するには、まずC-s RETと打ちます。 すると、探索文字列を読み取るためにミニバッファに移動します。 文字列をRETで終えると、探索を開始します。 文字列がみつからなければ、探索コマンドはエラーになります。

C-s RETはつぎのように動作します。 まず、C-sがインクリメンタルサーチを起動します。 インクリメンタルサーチは、特別な場合として、 引数が空であったときには一括型探索を起動するようにプログラムしてあります。 (さもなければ、そのような空の引数に意味はない。) C-r RETもこのように動作します。

しかし、C-s RETで実行される一括型探索は、 search-forwardをただちに呼び出すわけではありません。 まず、つぎの文字が単語探索を指示するC-wであるかどうか調べます。 See 節 10.3 単語探索

前向き/後向きの一括型探索は、 コマンドsearch-forwardsearch-backwardで実装されています。 これらのコマンドは通常と同じようにキーにバインドできます。 インクリメンタルサーチコマンドから呼び出せるようになっているのは、 歴史的な理由、および、 これらの機能にふさわしいキー列を選ぶ労力を削減できるという理由からです。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.3 単語探索

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Word%20Search"
"emacs/単語探索"へのコメント(無し)

単語探索は、単語の区切られ方を無視して、単語の列を探索します。 より正確には、空白1個で区切った数個の単語を打ち込むと、 単語と単語のあいだに複数個の空白/改行/句読点があったとしても、 それらの文字列をみつけだすことができます。

単語探索は、テキスト清書系で整形済みの文書を編集する場合に便利です。 整形した印刷出力を見ながら編集する場合、 ソースファイルのどこで行が区切られているのかわかりません。 単語探索を使えば、単語の区切られ方を知らなくても探索できます。

C-s RET C-w words RET
句読点などの詳細は無視して、wordsを探索する。
C-r RET C-w words RET
句読点などの詳細は無視して、後向きにwordsを探索する。

単語探索は、一括型探索の特別な場合であって、 C-s RET C-wで起動します。 この入力に続いて、探索文字列を入力し、 文字列はつねにRETで終えます。 一括型であるため、単語探索も引数を入力し終えるまで探索を開始しません。 単語探索は、正規表現を構築し、その正規表現で探索を行うことで 動作します。 See 節 10.4 正規表現探索

後向きの単語探索にはC-r RET C-wを使います。

前向き/後向きの単語探索は、それぞれ、 コマンドword-search-forwardword-search-backwardで 実装されています。 これらのコマンドは通常どおりキーに割り当てることができます。 インクリメンタルサーチコマンドから呼び出せるようになっているのは、 歴史的な理由、および、 これらの機能にふさわしいキー列を選ぶ労力を削減できるという理由からです。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.4 正規表現探索

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Regexp%20Search"
"emacs/正規表現探索"へのコメント(無し)

正規表現(regular expression、regexpと略す)とは、 一致する可能性がある一連の(無限個でもよい)文字列を表現するパターンです。 GNU Emacsでは、インクリメンタルサーチでも一括型探索でも、 正規表現を用いてつぎの一致箇所を探索できます。

正規表現によるインクリメンタルサーチを実行するには、 C-M-sisearch-forward-regexp)と打ちます。 このコマンドは、C-sと同様に、探索文字列を逐次読み取ります。 ただし、探索文字列をバッファのテキストに対して正確に照合するため のものとみなすのではなく、正規表現として扱います。 探索文字列にテキストを追加するごとに、 正規表現は長くなり、新たな正規表現を探索します。 (値は関係ない)前置引数を指定してC-sを起動しても、 前向きに正規表現の探索を始められます。 後向きに正規表現を探索するには、 C-M-risearch-backward-regexp)を使うか、 前置引数を指定してC-rを使います。

通常のインクリメンタルサーチにおいて特別な機能を持つコントロール文字は、 正規表現のインクリメンタルサーチでも同じ機能を持ちます。 探索の開始直後にC-sC-rを打つと、 最後のインクリメンタルサーチに用いた正規表現を再度使います。 つまり、正規表現を用いる探索とそうでない探索とには、 それぞれ独立のデフォルトがあるのです。 M-pM-nで参照できる探索リングも それぞれ別々です。

正規表現のインクリメンタルサーチでSPCを打つと、 改行を含めた任意個の白文字に一致します。 ちょうど1個の空白に一致させたいのであれば、 C-q SPCと打ちます。

正規表現のインクリメンタルサーチ中に正規表現に文字を加えると、 カーソルをもとに戻して探索し直すことがあります。 たとえば、`foo'を探索し終えたときに`\|bar'を追加したとします。 最初の`bar'が最初の`foo'に先行する場合には、 カーソルはまえに戻ります。

正規表現の一括型探索は、関数re-search-forwardre-search-backwardで行われます。 これらは、M-xで呼び出したり、キーに割り当てたり、あるいは、 C-M-s RETC-M-r RETとして 正規表現のインクリメンタルサーチの方法で起動したりできます。

正規表現のインクリメンタルサーチコマンドに前置引数を指定すると、 isearch-forwardisearch-backwardのように、 普通の文字列探索を行います。 See 節 10.1 インクリメンタルサーチ



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.5 正規表現の構文

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Regexps"
"emacs/正規表現の構文"へのコメント(無し)

正規表現には、特別な使い方をする少数の文字と その他の普通の文字から成る構文があります。 普通の文字は、 同じ文字だけに一致してそれ以外には一致しない単純な正規表現です。 特別な文字は、`$'、`^'、`.'、`*'、`+'、 `?'、`['、`]'、および、`\'です。 `\'が先行する場合を除いて、 正規表現に現れるこれら以外の文字は普通の文字です。

たとえば、`f'は特別な文字ではなく、通常の文字ですから、 文字列`f'に一致してそれ以外の文字列には一致しない正規表現です。 (これは、文字列`ff'には一致しない。) 同様に、`o'は、`o'だけに一致する正規表現です。 (大文字小文字を区別しない場合、 これらの正規表現は`F'や`O'にも一致するが、 これらは例外というよりは、『同じ文字列』の一般化として捉える。)

任意の2つの正規表現abを連結できます。 その結果は、aが文字列の始めの適当な部分に一致して、かつ、 bが文字列の残りの部分に一致する場合に、 文字列に一致するような正規表現です。

簡単な例として、正規表現`f'と`o'を連結すると、 正規表現`fo'を得ますが、 これは文字列`fo'だけに一致します。 簡単ですね。 多少とも複雑なことを行うには、特別な文字を使う必要があります。 以下にその一覧をあげます。

. (ピリオド)
特別な文字であり、改行以外の任意の1文字に一致する。 連結を使って`a.b'のような正規表現を作れる。 これは、`a'で始まり`b'で終る任意の3文字の文字列に一致する。

*
単独では構成要素ではない。 直前の正規表現を可能な限り反復することを意味する後置演算子である。 すなわち、(`o'が存在しない場合も含めて) `o*'は任意個の`o'に一致する。

`*'はつねに先行する最小の正規表現に適用される。 したがって、`fo*'は`fo'を繰り返すのではなく、 `o'を繰り返す。 この正規表現は`f'、`fo'、`foo'などに一致する。

`*'を用いた構成は、一致を処理するときには、 ただちに得られる限りの反復回数に展開される。 そうしてから、残りのパターンを処理する。 一致に失敗すると、バックトラック(後戻り)が発生して、 `*'を用いた構成の反復回数を減らして、 パターンの残りの部分が一致するようにする。 たとえば、文字列`caaar'に対して `ca*ar'を一致させることを考えてみる。 始めに、`a*'を3つの`a'すべてに一致させようとする。 しかし、残りのパターンが`ar'なのに`r'しか残っていないため、 この試みは失敗する。 そこで、つぎは`a*'を`a'2つだけに一致させる。 こうすると、残りの正規表現も正しく一致する。

+
`*'に似た後置演算子だが、 直前の正規表現に1回以上一致する必要がある。 たとえば、`ca+r'は、文字列`car'や`caaaar'には一致するが、 文字列`cr'には一致ない。 `ca*r'の場合は、上記の3つすべてに一致する。

?
`*'に似た後置演算子だが、 直前の正規表現に1回だけ一致するか、あるいは、1回も一致しない。 たとえば、`ca?r'は、`car'や`cr'に一致するが、 他のものには一致しない。

[ ... ]
`['で始まり`]'で終る文字集合を表す。 もっとも単純な場合は、 この2つの中括弧のあいだにある文字の1つ1つがこの文字集合に一致する。

したがって、`[ad]'は、`a'1文字か`d'1文字のどちらにも一致する。 `[ad]*'は、`a'と`d'だけから成る (空の文字列を含む)任意の文字列に一致する。 このことから、`c[ad]*r'は、 `cr'、`car'、`cdr'、`caddaar'などに一致することがわかる。

文字集合には、文字範囲の指定を含めることもでき、 始めの文字と終りの文字のあいだに`-'を書く。 つまり、`[a-z]'はすべてのASCII小文字に一致する。 範囲指定と個々の文字を自由に織り混ぜてよく、 `[a-z$%.]'のように書ける。 これは、任意のASCII小文字、`$'、`%'、ピリオドに一致する。

文字集合の内側では、正規表現の通常の特別な文字を 特別扱いしないことに注意。 文字集合の内側では、まったく別の特別な文字、 `]'、`-'、および、`^'が存在する。

文字集合に`]'を含めるには、 `]'を最初の文字として指定する必要がある。 たとえば、`[]a]'は、`]'や`a'に一致する。 `-'を含めるのであれば、`-'を文字集合の最初の文字か 最後の文字として指定して、範囲指定のあとに置く。 したがって、`[]-]'は、`]'と`-'の両方に一致する。

文字集合に`^'を含めるには、`^'を文字集合の2番目以降に置く。

大文字小文字を区別する探索で文字範囲を指定するときは、 範囲の両端を、大文字だけ、小文字だけ、あるいは、 英字以外だけで書くべきである。 `A-z'のような大文字小文字を混ぜた文字範囲の動作は、 定義が明確ではなく、将来のEmacsでは変更するかもしれない。

[^ ... ]
`[^'は文字の補集合の始まりを意味し、 指定した文字を除く任意の文字に一致する。 すなわち、`[^a-z0-9A-Z]'は、 英文字と数字を除くすべての文字に一致する。

`^'は先頭になければ文字集合では特別な意味を持たない。 `^'に続く文字は先頭にあるものとして扱われる (いいかえれば、ここでは`-'や`]'は特別な意味を持たない)。

文字の補集合は、一致しない文字として改行を指定しない限り、改行にも一致する。 この点は、grepのようなプログラムでの正規表現の扱い方と対照的。

^
空の文字列に一致する特別な文字で、テキスト行の先頭のみに一致する。 それ以外では、一致に失敗する。 したがって、`^foo'は、行頭にある`foo'に一致する。

$
`^'と似ていて、行末のみに一致する。 したがって、`x+$'は、 行末にある1文字以上の`x'から成る文字列に一致する。

\
2つの機能がある。 (`\'を含む)特別な文字をクォートする(意味を抑える)ことと、 特別な構成を導入すること。

`\'は特別な文字をクォートするので、 `\$'は文字`$'だけに一致する正規表現、 `\['は文字`['だけに一致する正規表現、 というようになる。

注意: 従来との互換性のために、特別な文字が、 それらの特別な意味をなしえない文脈で使われた場合には、 普通の文字として扱われます。 たとえば、`*foo'では、`*'の対象となる正規表現が直前にないため、 `*'は普通の文字として扱われます。 このようなふるまいに依存することはよい習慣ではありません。 特別な文字を書く位置に関係なく特別な文字はクォートするべきです。

多くの場合、任意の文字を伴う`\'はその文字だけに一致します。 しかし、いくつか例外があって、 `\'で始まる2文字列が特別な意味を持つ場合があります。 2文字目にくる文字は、 単独で使った場合には普通の文字として扱われるものです。 以下に`\'の構成を列挙します。

\|
選択肢を指定する。 `\|'をあいだに伴った2つの正規表現abは、 abのいずれかに一致する文字列に一致する正規表現となる。

したがって、`foo\|bar'は、`foo'か`bar'に一致するが、 それ以外の文字列には一致しない。

`\|'は、周囲にある適用しうる正規表現の中でも最大のものに適用される。 `\|'によるグループ化を制限するのは、 これを囲む`\( ... \)'によるグループ化だけ。

何度`\|'を使っても処理できるだけの十分なバックトラック能力がある。

\( ... \)
以下の3つの目的を果たすグループ化のための構成。

  1. 他の操作に使うために一連の選択肢`\|'を括る。 したがって、`\(foo\|bar\)x'は、 `foox'か`barx'のいずれかに一致する。

  2. 後置演算子、`*'、`+'、`?'を適用できるように、 複雑な正規表現を括る。 したがって、`ba\(na\)*'は、 `bananana'のように、(0個以上の)任意個の 文字列`na'に一致する。

  3. あとで参照できるように、一致した部分文字列を記録する。

最後の使い方は、括弧によるグループ化という考え方から 派生したものではない。 同一の`\( ... \)'構成に与えた2つめの別の機能である。 実用上、これら2つの意味が混同されることはない。

\d
d番目に現れた`\( ... \)'に一致したテキストと 同じテキストに一致する。

一致を処理するときには、`\( ... \)'構成の末尾に達すると、 この構成に一致したテキストの始めと終りを記録する。 そして、正規表現のそれよりうしろでは、 『d番目に現れた`\( ... \)'に一致したテキスト』という意味で `\'に続けて数字dを使える。

1つの正規表現内に現れる最初の9個の`\( ... \)'に一致する文字列には、 正規表現中で開き括弧が現れた順に、1から9までの番号を割りふる。 そのため、`\1'から`\9'で、 対応する`\( ... \)'に一致したテキストを参照できる。

たとえば、`\(.*\)\1'は、改行を含まない文字列で、かつ、 前半と後半が同一である文字列に一致する。 `\(.*\)'は前半部分に一致し、それはどのようなものでもかまわない。 一方、それに続く`\1'は、 前半部分とまったく同じテキストに一致しなければならない。

ある`\( ... \)'が、 (直後に`*'がある場合などに簡単に起こりえる) 複数回一致する場合には、最後に一致したものだけを記録する。

\`
空の文字列に一致するが、 一致対象であるバッファや文字列の先頭に限る。

\'
空の文字列に一致するが、 一致対象であるバッファや文字列の末尾に限る。

\=
空の文字列に一致するが、ポイント位置に限る。

\b
同じく空の文字列に一致するが、単語の先頭や末尾に限る。 したがって、`\bfoo\b'は、単語として独立して現れる`foo'に一致する。 `\bballs?\b'は、単語として独立して現れる `ball'や`balls'に一致する。

`\b'は、 バッファの先頭や末尾にあるテキストとは無関係に、 バッファの先頭や末尾にも一致する。

\B
空の文字列に一致するが、単語の先頭や末尾以外に限る。

\<
空の文字列に一致するが、単語の先頭に限る。 `\<'は、単語構成文字が続く場合に限って、 バッファの先頭にも一致する。

\>
空の文字列に一致するが、単語の末尾に限る。 `\>'は、単語構成文字で終了している場合に限って、 バッファの末尾にも一致する。

\w
任意の単語構成文字に一致する。 エディタの構文テーブルによってこの文字が決まる。 see 節 28.6 構文テーブル

\W
単語構成文字以外の文字に一致する。

\sc
構文がcである文字だけに一致する。 ここで、cは構文コードを表す文字。 たとえば、`w'は単語構成要素を、 `-'は白文字を、`('は開き括弧を表すといった具合。 (改行を含む)白文字は、`-'や空白で表す。

\Sc
構文がcでない任意の文字に一致する。

単語や構文に関連する構成要素は、 構文テーブル(see 節 28.6 構文テーブル)の設定で制御されます。

複雑な正規表現を以下に示します。 これは、任意個の白文字がうしろに続く文末を認識するためにEmacsが使うものです。 空白とタブ文字を区別できるように、Lispの構文で示してあります。 Lisp構文では、文字列定数はダブルクォートで始まり、 ダブルクォートで終ります。 `\"'は正規表現の一部としてのダブルクォートを表し、 `\\'は正規表現の一部としてのバックスラッシュを表します。 `\t'はタブ文字、`\n'は改行文字を表します。

 
"[.?!][]\"')]*\\($\\|\t\\|  \\)[ \t\n]*"

この正規表現は4つの部分が繋がってできています。 ピリオド、`?'、`!'のいずれかに一致する文字集合。 閉じ中括、2種類の引用符、括弧に一致する文字集合の任意回数の繰り返し。 バックスラッシュ付きの括弧で括った、 行末、タブ、空白2つのいずれかに一致する選択肢。 白文字に一致する文字集合の任意回数の繰り返し。

これと同じ正規表現を対話的に入力するときには、 タブを入力するにはTABを打ち、 改行を入力するにはC-jを打ちます。 また、Lisp構文上ではバックスラッシュを2つ続けてますが、 対話的に入力するには、1つのバックスラッシュだけを打ちます。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.6 探索と大文字小文字の区別

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Search%20Case"
"emacs/探索と大文字小文字の区別"へのコメント(無し)

Emacsのインクリメンタルサーチでは、小文字だけで探索文字列を指定すると、 探索対象のテキストの大文字小文字の違いを通常無視します。 したがって、`foo'を探索するように指定すると、 `Foo'にも`foo'にも一致します。 正規表現、特に文字集合の場合でも同様です。 `[ab]'は、`a'、`A'、`b'、`B'のいずれにも一致します。

インクリメンタルサーチする探索文字列のどこかに大文字があると、 大文字小文字を区別して探索します。 したがって、`Foo'の探索では、 `foo'や`FOO'をみつけだせません。 このことは、文字列の探索だけでなく正規表現の探索にもあてはまります。 探索文字列から大文字を消去すれば、この効果はなくなります。

変数case-fold-searchnilを設定すれば、 大文字小文字の違いを含めて、すべての文字はそのとおりに一致するようになります。 これは、バッファごとの変数です。 変数を変更してもカレントバッファだけに影響しますが、 変更可能なデフォルトの値があります。 See 節 28.2.4 ローカル変数。 この変数は、置換コマンド(see 節 10.7 置換コマンド)や ミニバッファの履歴探索コマンド(see 節 4.4 ミニバッファ履歴)が 行う探索を含む、一括型探索にも適用されます。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.7 置換コマンド

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Replace"
"emacs/置換コマンド"へのコメント(無し)

大域的な探索置換操作は、他のエディタ (13) で必要なほどEmacsでは必要はありませんが、Emacsでも使えます。 多くのエディタにあるような単純なコマンドM-x replace-stringの他にも、 パターンの各出現ごとに置換するかどうか尋ねてくる M-x query-replaceコマンドがあります。

置換コマンドは、通常、ポイントからバッファの末尾までのテキストを操作します。 しかし、暫定マーク(transient-mark)モードでは、 マークが活性である場合にはリージョンを操作します。 置換コマンドはどれも、 1つの文字列(や正規表現)を1つの置換文字列に置き換えます。 コマンドexpand-region-abbrevs(see 節 22.3 略語展開の制御)を使って、 いくつかの置き換えを並行に行うことができます。

10.7.1 無条件置換    Replacing all matches for a string.
10.7.2 正規表現による置換    Replacing all matches for a regexp.
10.7.3 置換コマンドと大文字小文字の区別    How replacements preserve case of letters.
10.7.4 問い合わせ型置換    How to use querying.



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.7.1 無条件置換

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Unconditional%20Replace"
"emacs/無条件置換"へのコメント(無し)

M-x replace-string RET string RET newstring RET
stringのすべての出現をnewstringで置換する。
M-x replace-regexp RET regexp RET newstring RET
正規表現regexpに一致するものすべてをnewstringで置換する。

ポイント以降にある`foo'のすべての出現を `bar'で置き換えるには、2つの引数`foo'と`bar'を指定した コマンドM-x replace-stringを使います。 置換はポイント以降でのみ実施されますから、 バッファ全体に対して置換を行いたいときには、 まずバッファの先頭に移動しておく必要があります。 バッファの末尾までに現れるすべての出現を置換します。 バッファの一部に置換を限定したいときには、 置換を実行するまえに、バッファの当該部分にナロイングしておきます (see 節 27.20 ナロイング)。 暫定マーク(transient-mark)モードにおいては、 リージョンが活性のときには、置換はリージョン内に限定されます。

replace-stringを終了すると、 ポイントは最後に置換した出現箇所に置かれます。 マークは(replace-stringコマンドを起動したとき) 以前のポイント位置に設定されます。 その位置に戻るにはC-u C-SPCを使います。

数引数を指定すると、 単語区切りで囲まれた出現だけを置換対象とします。 引数の値は関係ありません。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.7.2 正規表現による置換

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Regexp%20Replace"
"emacs/正規表現による置換"へのコメント(無し)

M-x replace-stringコマンドは、 1つの文字列に正確に一致するものだけを置き換えます。 これに類似したコマンドM-x replace-regexpは、 指定したパターンに一致する任意のものを置き換えます。

replace-regexpでは、 newstringが定数である必要はありません。 regexpに一致したものの全体あるいはその一部を参照できます。 newstringの中の`\&'は、 置換対象の文字列全体(つまり、regexpに一致したものの全体)を 表します。 newstringの中の`\d'(dは数字)は、 regexpの中のd番目の括弧のグループ化部分に 一致した部分を表します。 置き換えるテキスト内に`\'を含めるには、 `\\'と入力する必要があります。

 
M-x replace-regexp RET c[ad]+r RET \&-safe RET

たとえばこの例は、`cadr'を`cadr-safe'で、 `cddr'を`cddr-safe'で置換します。

 
M-x replace-regexp RET \(c[ad]+r\)-safe RET \1 RET

この例は、逆の置換を行います。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.7.3 置換コマンドと大文字小文字の区別

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Replacement%20and%20Case"
"emacs/置換コマンドと大文字小文字の区別"へのコメント(無し)

置換コマンドの第1引数がすべて小文字である場合、 case-fold-searchnil以外であるときには、 大文字小文字を区別せずに置換対象を探索します。 case-fold-searchnilであるときには、 すべての探索において大文字小文字を区別します。

さらに、引数newstringが、すべて小文字、あるいは、 一部が小文字のときには、置換コマンドは、 各置換対象の大文字小文字のパターンを保存しようとします。 つまり、コマンド

 
M-x replace-string RET foo RET bar RET

は、小文字の`foo'を小文字の`bar'に、 すべて大文字の`FOO'を`BAR'に、 大文字で始まる`Foo'を`Bar'に置換します。 (replace-stringが区別できるのは、これら3つの選択肢、 つまり、小文字のみ、すべて大文字、大文字で始まるだけ。)

置換文字列に大文字を使ったときには、 これを挿入するときは大文字は大文字のままです。 第1引数に大文字を使ったときには、 第2引数では大文字小文字を変換せずにつねに指定どおりに置き換えます。 同様に、case-replacecase-fold-searchnilを設定すると、 大文字小文字を変換せずに置換します。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.7.4 問い合わせ型置換

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Query%20Replace"
"emacs/問い合わせ型置換"へのコメント(無し)

M-% string RET newstring RET
M-x query-replace RET string RET newstring RET
stringのいくつかの出現をnewstringで置換する。
C-M-% regexp RET newstring RET
M-x query-replace-regexp RET regexp RET newstring RET
正規表現regexpに一致するもののいくつかをnewstringで置換する。

`foo'のすべての出現ではなく、 そのうちのいくつかだけを`bar'に変更したいときには、 通常のreplace-stringを使うことはできません。 かわりに、M-%query-replace)を使います。 このコマンドは`foo'の出現をみつけるたびに、 その出現を表示し、置換するかどうか聞いてきます。 query-replaceに数引数を指定すると、 単語区切り文字で区切られた出現だけを対象とします。 通常どおりcase-replacenil以外であれば、 replace-stringと同じく、 このコマンドも大文字小文字の違いを保存します。

問い合わせることを除けば、 query-replacereplace-stringと同様に動作し、 query-replace-regexpreplace-regexpと同様に動作します。 このコマンドは、C-M-%で実行できます。

stringの出現やregexpに一致したものが表示されたときに 打てる文字はつぎのとおりです。

SPC
出現をnewstringで置換する。

DEL
この出現を置換せずにつぎの出現箇所に進む。

, (カンマ)
この出現を置換し、結果を表示する。 そして、つぎに何をするか指示する文字を聞いてくる。 置換自体はすでに完了しているので、 この状況ではDELSPCは等価であり、 つぎの出現箇所へ移動するという意味。

この時点では、C-r(下記参照)を打って、置換したテキストを変更できる。 また、C-x uと打って、置換をアンドゥする(もとに戻す)こともできるが、 そうすると、query-replaceを終了してしまう。 さらに先の置換を行いたいときには、 C-x ESC ESC RETを使って再開する必要がある (see 節 4.5 ミニバッファコマンドの繰り返し)。

RET
これ以上何も置換しないで終了する。

. (ピリオド)
この出現を置換してから、これ以上探索せずに終了する。

!
これ以降、問い合わせずに残りの出現すべてを置換する。

^
誤って変更してしまった場合などに、 1つまえの出現箇所(あるいは置換してしまった出現箇所)に戻る。 これは、マークリングから位置を取り出して動作する。 query-replaceは直前の1つの置換位置だけを記録するため、 ^を続けて入力しても意味はない。

C-r
単にnewstringで置換するだけでなく、 この出現を編集する必要がある場合などに、再帰編集レベルに入る。 編集し終えてC-M-cで再帰編集を抜けると、つぎの出現箇所に移動する。 see 節 27.24 再帰編集レベル

C-w
出現を削除してから、C-rと同様に再帰編集レベルに入る。 再帰編集を使って、削除したstringの出現を置き換えるテキストを挿入する。 編集し終えてC-M-cで再帰編集を抜けると、つぎの出現箇所に移動する。

C-l
画面を再表示する。 そうしたら、この出現に対して何を行うかを指示する別の文字を打つ必要がある。

C-h
これらのオプションの要約メッセージを表示する。 そうしたら、この出現に対して何を行うかを指示する別の文字を打つ必要がある。

上記のコマンドの別名である文字が他にもいくつかあります。 ynqは、それぞれ、 SPCDELRETに等価です。

これ以外の文字はquery-replaceを終了し、 その文字はキー列の一部になります。 したがって、C-kと打つと、 query-replaceを終了してから、行末までをキルします。

一度抜けたquery-replaceを再開するには、 C-x ESC ESCを使います。 このコマンドはquery-replaceを繰り返します。 というのは、query-replaceはミニバッファで引数を読み取るからです。 See 節 C-x ESC ESC

ファイル名に対して正規表現に一致する部分を置換することで、 ファイルの改名、コピー、リンクを行うdiredコマンドについては、 26.9 diredでのファイル名の変換も参照してください。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

10.8 他の探索繰り返しコマンド

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=emacs&node=Other%20Repeating%20Search"
"emacs/他の探索繰り返しコマンド"へのコメント(無し)

正規表現に一致するものをみつけるコマンドは、他にもいくつかあります。 それらは、ポイント位置からバッファの末尾までを操作対象とします。 さらに、パターンに大文字が含まれていないときや、 case-fold-searchnil以外であるときには、 大文字小文字の違いを無視して一致を探します。

M-x occur RET regexp RET
regexpに一致するものを含むバッファ内の各行の一覧を表示する。 数引数で、一致した各行の前後何行を表示するか指定する。 デフォルトは0行。 バッファの一部に探索を制限するには、 その部分にナロイングする(see 節 27.20 ナロイング)。

出力を表示したバッファ`*Occur*'は、 もとの文脈での出現位置を探すためのメニューとして機能する。 `*Occur*'に表示された出現をMouse-2でクリックするか、あるいは、 ポイントをそこに置いてRETを打つ。 この操作により、探索を行ったバッファに切り替え、 選択した出現のもとの位置にポイントを移動する。

M-x list-matching-lines
M-x occurと同じ。

M-x count-matches RET regexp RET
ポイント以降でregexpに一致するものの個数を表示する。

M-x flush-lines RET regexp RET
ポイント以降にあってregexpに一致するものを含む各行を削除する。

M-x keep-lines RET regexp RET
ポイント以降にあってregexpに一致するものを 含まない各行を削除する。

さらに、Emacsからgrepを使って、 一連のファイルに対して正規表現に一致するものを探して、 一致するものを含むファイルを順番に、あるいは、 任意の順に訪問できます。 See 節 21.2 Emacs下でのgrepによる探索


[ << ] [ >> ]           [表紙] [目次] [索引] [検索] [上端 / 下端] [?]