[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30. 検索と照合

GNU Emacsには、バッファ内のあるテキストを検索する方法が二つあります。 それは文字列そのものによる検索と正規表現による検索です。 正規表現の検索の後では、 一致データ(match data)を調べて、 どのテキストが正規表現の全体やその一部分に一致したのか判別することができます。

`skip-chars…'関数群も 一種の検索を行ないます。See section 文字を飛ばす


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.1 文字列の検索

以下の関数はバッファのテキストを検索するプリミティブ関数です。 プログラムから使うことを想定していますが、 対話的に呼び出すこともできます。 その場合、 プロンプトを出して検索する文字列の入力を促します。 limitnoerrornilに設定され、 repeatは1に設定されます。

Command: search-forward string &optional limit noerror repeat

この関数は、stringに完全一致するテキスト文字列を求め、 ポイントから順方向に検索します。 もし成功すれば、見つかったものの終りにポイントを置いて、 新しいポイントの値を返します。 もし見つからなければ、 戻り値と副作用はnoerrorによります(以下参照)。

以下の例で、ポイントははじめ、行頭にあります。 そして(search-forward "fox")によって、 `fox'の最後の文字の後に動かされます。

 
---------- Buffer: foo ----------
∗The quick brown fox jumped over the lazy dog.
---------- Buffer: foo ----------

(search-forward "fox")
     ⇒ 20

---------- Buffer: foo ----------
The quick brown fox∗ jumped over the lazy dog.
---------- Buffer: foo ----------

引数limitは検索にたいする上限を指定します (カレント・バッファ内の位置でなくてはいけません)。 この位置を越えるものとは照合しません。 もしlimitが省略されたかnilの場合、 アクセス可能なバッファの末尾になります。

検索が失敗したときの動作は、noerrorの値によります。 もしnoerrornilならば、 search-failedエラーが通知されます。 もしnoerrortの場合、 search-forwardnilを返し何もしません。 もしnoerrornilでもtでもない場合、 search-forwardはポイントを上限まで動かし、nilを返します (この場合、新しいポイントの値を返した方が一貫性があるのですが、 nilという値に依存したプログラムがあるようです)。

もしrepeatが与えられた場合(正数でなければなりません)、 その回数だけ(毎回前の照合の末尾から)検索を繰り返します。 もしこの連続検索が成功したら、この関数は、成功です。 ポイントを動かして新しい値を返します。さもないと検索は失敗です。

Command: search-backward string &optional limit noerror repeat

この関数は、ポイントから逆方向にstringを検索します。 これはsearch-forwardと対応していますが、 逆方向に検索し、一致した文字列の先頭にポイントを置きます。

Command: word-search-forward string &optional limit noerror repeat

この関数は、stringに一致する「語」を求め、 ポイントから順方向に検索します。 もし見つかったら、 一致の終りにポイントを置き、 ポイントの新しい値を返します。

語の照合では、stringを語の列であるとみなし、 語を分離する句読点文字を無視します。 バッファから同じ語の列を検索します。 語はそれぞれバッファ中で分離していなければなりません (語`ball'の検索は語`balls'には一致しません) が、句読点文字と余白の細部は無視します (`ball boy'の検索は`ball. Boy!'に一致します)。

この例において、ポイントは最初バッファの先頭にあり、 検索の後`y'`!'の間に移動します。

 
---------- Buffer: foo ----------
∗He said "Please!  Find
the ball boy!"
---------- Buffer: foo ----------

(word-search-forward "Please find the ball, boy.")
     ⇒ 35

---------- Buffer: foo ----------
He said "Please!  Find
the ball boy∗!"
---------- Buffer: foo ----------

limitが非nil (カレント・バッファ内の位置でなくてはいけません)の場合、 これは検索にたいする上限になります。 この位置を越えるものとは照合しません。

noerrornilの場合、 検索が失敗するとword-search-forwardはエラーを通知します。 noerrortの場合、 検索が失敗するとエラーを通知する代わりにnilを返します。 noerrornilでもtでもない場合、 これはポイントをlimit(またはバッファの末尾)まで動かし、 nilを返します。

もしrepeatが非nilの場合、 その回数だけ検索を繰り返します。 最後に一致したものの終りにポイントを位置づけます。

Command: word-search-backward string &optional limit noerror repeat

この関数は、stringに一致する語を求め、 ポイントから逆方向に検索を行ないます。 この関数は、word-search-forwardと対応していますが、 逆方向に検索し、 通常は一致した文字列の先頭にポイントを置きます。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.2 正規表現

正規表現(regular expression)(略してregexp)は、 文字列の(ときには無限)集合を示すパターンです。 regexpにたいする一致の検索は、非常に強力な操作です。 この節では、regexpの書き方を説明し、 次の節ではその検索のしかたを述べます。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.2.1 正規表現の構文

正規表現は、その中のいくつかの文字が特殊な構文要素であり、 それ以外のものは通常の(ordinary)文字であるという構文をもっています。 通常の文字は、その文字自身にのみ一致するという単純な正規表現です。 特殊文字は`.'`*'`+'`?'`['`]'`^'`$'`\'です。 特殊文字が新たに定義されることはありません。 正規表現中のこのほかのすべての文字は、 `\'がその前に置かれないかぎり、 通常の文字となります。

たとえば、`f'は特殊文字ではありませんから通常の文字で、 したがって`f'は、文字列`f'に一致し、そのほかのものには一致 しない正規表現です (これは文字列`ff'には一致しません)。 同様に、`o'`o'のみに一致する正規表現です。

任意の二つの正規表現abをつなぐことができます。 abを連結した結果は、 aがある文字列の頭の部分に一致し、 bがその文字列の残りの部分に一致する場合、その文字列に一致する 正規表現になります。

簡単な例として、 正規表現`f'`o'を連結して 正規表現`fo'を得ることができます。 これは文字列`fo'だけに一致します。 ここまではまだあたりまえの話です。 何か強力なことを行なうためには、 特殊文字を用いる必要があります。 以下にそれらのリストを示します。

. (終止符)

は、改行をのぞくどんな1文字にも一致する特殊文字です。 連結を用いることで、 `a'で始まり`b'で終る任意の3文字の文字列に 一致する`a.b'のような正規表現を作ることができます。

*

は、これだけでは構文要素になりません。 これは先行する正規表現をできるかぎり繰り返すことを意味する後置演算子です。 `fo*'における`*'`o'に適用されるため、 `fo*'は一つの`f'の後ろに 任意個の`o'が続くものに一致します。 0個の`o'も許します。 `fo*'`f'にも一致するのです。

`*'は常に、先行するできるかぎり小さくとった正規表現に適用します。 このため`fo*'`o'を繰り返しますが、 `fo'を繰り返すわけではありません。

一致処理では、 連続して見つかるかぎりの繰り返しに`*'要素が一致するように処理します。 その後、残りのパターンの処理を続けます。 それが失敗すると、 `*'修飾された正規表現の一致のいくつかを捨てることで、 パターンの残りに一致することが可能になる場合に、 バックトラックが起こります。 たとえば、文字列`caaar'`ca*ar'を一致させる場合、 最初`a*'を三つの`a'すべてに一致させようとします。 しかし、残りのパターンは`ar'であるのに、 一致対象として残っているのは`r'だけなので、 この試みは失敗します。 次の選択肢は`a*'に対し二つだけ`a'を一致させることです。 この選択により、この正規表現の残りの部分の一致は成功します。

バックトラックがループする場合、 ネストした繰り返し演算子は非常に遅くなります。 たとえば、正規表現`\(x+y*\)*a'を 何時間もかかるかもしれません。 この遅さは、Emacsが35個の`x'の可能な組み合わせを、 結局どれ一つとしてうまくいかないことがわかるまで、 すべて試さなければならないためです。 正規表現が速く処理できるよう、 ネストした繰り返しは注意深く調べてください。

+

先行する正規表現が少なくとも1回は一致しなくてはいけない、 という点をのぞき`*'に似た後置演算子です。 このため、 たとえば、`ca+r'は文字列`car'`caaaar'には一致しますが、 文字列`cr'には一致しません。 一方`ca*r'はこの三つの文字列すべてに一致します。

?

先行する正規表現が1回一致するかあるいはまったく一致しなくてもよい、 という点をのぞき`*'に似た後置演算子です。 このため、 たとえば、`ca?r'`car'にも`cr'にも一致しますが、 それ以外のものには一致しません。

[ … ]

`['は、`]'で終る文字集合(character set)を始めます。 一番単純な場合、二つの角括弧の間にある文字群が集合を構成します。 このため、`[ad]'は1個の`a'か1個の`d'に一致し、 `[ad]*'`a'もしくは`d'だけからなる文字列 (空文字列も含む)に一致します。 これにより`c[ad]*r'`cr'`car'`cdr'`caddaar'などに一致することになります。

通常の正規表現における特殊文字は、 文字集合の中では特別扱いしません。 文字集合の中では、 まったく別の特殊文字の集合`]'`-'`^'を用います。

文字の範囲を表わすのに`-'を使います。 `-'を二つの文字の間に書くことで文字の範囲を表わします。 したがって、`[a-z]'はすべての小文字に一致します。 範囲と個々の文字は、どのように混じっていてもかまいません。 `[a-z$%.]'は、 小文字か`$'`%'`.'に一致します。

`]'を文字集合の中に含むには、それを最初の文字としなくてはいけません。 たとえば、`[]a]'`]'`a'に一致します。`-'を含む には、`-'を集合の最初の文字とするか範囲の直後に置きます (`-'の 置き場所を作るため、 独立した(つまり範囲でない)1個の文字cを範囲`c-c'と 入れ替えるといいでしょう)。 `-'`]'だけを含む集合を書くには、 `[]-]'あるいは`[]---]'とします (原著では「できません」とあります)。

集合に`^'を含めるには、 それを集合の最初の文字にならないようにします。

[^ … ]

`[^'は、指定した文字以外の文字に一致する 文字補集合(complement character set)を始めます。 このため`[^a-z0-9A-Z]'は、 英文字や数字以外のどの文字にも一致します。

文字集合の`^'は、 最初の文字として使われないかぎり特別扱いされません。 `^'に続く文字は、あたかもそれが最初のものであるかのように扱います (したがってそこでは`-'`]'を特別扱いしません)。

改行が一致しない文字の一つとして記述されてないかぎり、 文字補集合は改行に一致します。

^

は、空文字列に一致する特殊文字ですが、 これは一致が行なわれるテキスト中の行頭でのみ一致します。 さもないと、これは何にも一致しません。 このため、`^foo'は行頭にある`foo'に一致します。

バッファにたいしてでなく文字列にたいして一致を行なうとき、 `^'は文字列の先頭か改行文字`\n'の後に一致します。

$

は、`^'に似ていますが、行末でのみ一致します。 このため、 `x+$'は行末にある一つ以上の`x'からなる文字列に一致します。

バッファにたいしてでなく文字列にたいして照合を行なうとき、 `$'は文字列の末尾か改行文字`\n'の前に一致します。

\

は、二つの働きをします。 それは(`\'を含む)特殊文字をquoteするのと、 追加された特殊構文要素を導入することです。

`\'は特殊文字をquoteするため、 `\$'`$'にのみ一致する正規表現であり、 `\['`['にのみ一致する正規表現であるなどなど、 ということになります。

`\'はLisp文字列(see section 文字列型) のリード構文で特別な意味があり、 `\'でquoteしなければならないことに注意してください。 たとえば、`\'文字と一致する正規表現は`\\'です。 2文字の`\\'を含むLispの文字列を書くとき、 Lisp構文では各`\'を別な`\'でquoteする必要があります。 したがって、`\'と一致する正規表現のリード構文は"\\\\"です。

注意:過去との互換性のため、 特殊文字はその特別な意味が意味をもたない文 脈では普通の文字として扱われます。 たとえば、`*foo'では`*'の作用すべき先行正規表現がないため、 `*'を通常の文字として扱います。 この動きに依存するのはよいことではありません。 それがどこに現われるにせよ、 特殊文字はquoteしておいたほうがよいでしょう。 ほとんどの場合、任意の文字が後続する`\'は、その文字にのみ一致します。 しかしながら、いくつか例外が存在します。 それは`\'が先行するときに特別な構文要素になる文字の場合です。 このような文字は、それだけの場合、常に通常の文字になります。 以下にこの`\'構成要素の表を示します。

\|

は、選択肢を示します。 `\|'が間にある二つの正規表現abは、 aあるいはbに一致するものに一致する正規表現を構成します。

このため、`foo\|bar'`foo'にも`bar'にも一致しますが、 それ以外の文字列には一致しません。

`\|'は、その前後のできるだけ大きくとった正規表現に適用します。 それを囲む`\( … \)'の一団のみが、 `\|'による分割の勢力を限ることができます。

複数の`\|'を処理する完全なバックトラックの機能があります。

\( … \)

は三つの目的をもつ分割の構文要素です。

  1. ほかの操作に対し、`\|'選択肢の集合を囲みます。 よって`\(foo\|bar\)x'は、 `foox'にも`barx'にも一致します。
  2. `*'のような後置演算子が作用する正規表現を囲みます。 よって`ba\(na\)*'は、 文字列`na'の (0回以上の) 繰返しをもつ`bananana'などに一致します。
  3. 将来参照するため一致した部分文字列を記録します。

この最後の用法は括弧による分割という考えからきたものではありません。 両方の意味が実際には競合しないため、 同じ`\( … \)'構文要素の第2の意味として、 たまたまこれに与えた機能となっています。 次にこの機能を説明します。

\digit

digit番目に出てきた`\( … \)'構文要素で一致したのと 同じテキストと一致します。

いい換えると、 `\( … \)'構文要素の後、 この構成に一致したテキストの始めと終りを覚えます。 `\'の後にdigitを続けたものをこの後の正規表現で用い、 digit番目に`\( … \)'構成に一致したものが何であれ、 それと同じテキストに一致させることができます。

正規表現中に現われる`\( … \)'構文要素に一致した 最初の九つの文字列には、 その開き括弧が正規表現中に現われた順に 1から9の番号を割振ります。 対応する`\( … \)'構成に一致するテキストは、 `\1'から`\9'で引用することができます。

たとえば、`\(.*\)\1'は二つの同じものからなる改行を含まないすべての 文字列に一致します。 `\(.*\)'は任意の頭の半分に一致し、 それに続く`\1'はそれとまったく同じテキストに一致しなくてはいけません。

\w

は、語を構成するすべての文字に一致します。 エディタの構文テーブルで、 どの文字が語を構成する文字かを決定します。See section 構文テーブル

\W

は、語を構成しないすべての文字に一致します。

\scode

は、その構文がcodeであるすべての文字に一致します。 codeは構文符号を示す文字です。 `w'は語を構成するものにたいするもの、 `-'は空白にたいするもの、 `('は開き括弧にたいするもの、などなどです。 構文符号と対応する文字の一覧はSee section 構文テーブル

\Scode

は、その構文がcodeでないすべての文字に一致します。

以下の正規表現の構文要素は、空文字列に一致します。 つまり、文字には当たりません。 しかし、一致は文脈には依存します。

\`

は、それがバッファや、 照合する文字列の先頭にある場合のみ、 空文字列に一致します。

\'

は、それがバッファや、 照合する文字列の末尾にある場合のみ、 空文字列に一致します。

\=

は、それがポイントの位置にある場合のみ、 空文字列に一致します。 (この構文要素は文字列にたいしての照合では定義されません。)

\b

は、それが語頭か語尾にある場合のみ、 空文字列に一致します。 このため`\bfoo\b'は独立した単語として現われた`foo'に一致します。 `\bballs?\b'は、 独立した単語としての`ball'にも`balls'にも一致します。

\B

は、それが語頭にも語尾にもない場合、 空文字列に一致します。

\<

は、それが語頭にある場合のみ、 空文字列に一致します。

\>

は、それが語尾にある場合のみ、 空文字列に一致します。

すべての文字列が、正しい正規表現というわけではありません。 たとえば、不釣り合いな角括弧は不正ですし (`[]]'といった例外はありますが)、 単一の`\'で終る文字列も不正です。 不正な正規表現を検索関数のいずれかに渡した場合は、 invalid-regexpエラーが通知されます。

Function: regexp-quote string

この関数は、stringに完全に一致しほかのものに一致しない正規表現の 文字列を返します。これで正規表現を受けつける関数の呼出しで、 完全な文字列の一致を要求することができます。

 
(regexp-quote "^The cat$")
     ⇒ "\\^The cat\\$"

完全な文字列の一致と正規表現で記述した文脈との組み合せに、 regexp-quoteを使うということもできます。 次の例では、 空白で囲んだstringという値の文字列を検索しています。

 
(re-search-forward
 (concat "\\s-" (regexp-quote string) "\\s-"))

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.2.2 複雑な正規表現の例

以下に、 文末とそれに続く空白を認識するのにEmacsが用いている 複雑なregexpを示します。 これは変数 sentence-endの値です。

まずこのregexpを、 スペースとタブ文字が区別できるようになるLisp構文の文字列として 示すことにします。 Lisp構文において、文字列定数は二重引用符で始まり二重引用符で終ります。 `\"'は文字列の一部としての二重引用符を示し、 `\\'は文字列の一部としてのバックスラッシュを、 `\t'はタブを、 `\n'は改行を示します。

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

一方、変数sentence-endを評価すると、 以下のものが得られます。

 
sentence-end
⇒
"[.?!][]\"')}]*\\($\\| $\\|  \\|  \\)[       
]*"

ここでは、タブと改行はそのまま出力されます。

この正規表現は、連続した四つの部分から構成されており、 以下のように解読することができます。

[.?!]

第1の部分は終止符、疑問符、感嘆符の3文字いずれかに一致する文字集合です。 一致はこの3文字の内のいずれか1文字で始まらなければなりません。

[]\"')}]*

第2の部分は、 0回かそれ以上繰り返される任意の閉じ括弧や引用符に一致し、 これが終止符、疑問符、感嘆符に後続することになります。 \"はLisp構文で文字列中の二重引用符です。 末尾の`*'は直前の正規表現(この場合は文字集合)が、 0回以上繰り返すことを示します。

\\($\\| $\\|\t\\|  \\)

第3の部分は、文末に続く空白、すなわち、 行末、タブ、二つのスペースに一致します。 二重のバックスラッシュは括弧と縦棒が正規表現の構文であることを示します。 括弧が分割を制限し、 縦棒が選択肢を分割しています。 ドル記号を行末との一致に使っています。

[ \t\n]*

最後の部分は、文末に必要な最低限の空白に続く、余分な任意の空白です。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.3 正規表現の検索

GNU Emacsでは、次にあるregexpへの一致を求め、 段階的もしくは普通の検索を行なうことができます。 段階的検索のコマンドについては(emacs)Regexp Search section `Regular Expression Search' in The GNU Emacs Manualを参照してください。 ここで述べるのは、プログラムに便利な検索関数だけです。 一番重要なのがre-search-forwardです。

Command: re-search-forward regexp &optional limit noerror repeat

この関数は、 カレント・バッファで正規表現regexpに一致するテキスト文字列を求め、 順方向に検索します。 これはregexpに一致しないテキストをすべて飛び越し、 最初に一致したテキスト文字列の終りにポイントを置きます。 ポイントの値を返します。

もしlimitが非nil (これはカレント・バッファ内の位置でなくてはいけません)の場合、 これは検索の上限になります。 この位置を越えるものとは照合しません。

検索が失敗したときの動作は、noerrorの値によります。 もしnoerrornilならば、 search-failedエラーが通知されます。 もしnoerrortの場合、 re-search-forwardは何もせずnilを返します。 もしnoerrornilでもtでもない場合、 re-search-forwardは ポイントをlimit(またはバッファの終り)まで動かし、 nilを返します。

もしrepeatが与えられた場合 (正数でなければなりません)、 その回数だけ (毎回前の一致の末尾から) 検索を繰り返します。 もしこの連続検索が成功したら、 ポイントを動かし新しい値を返します。 さもないと検索は失敗します。

次の例において、ポイントは最初`T'の前に置かれています。 検索の呼出しを評価した後、ポイントを行末 (`hat'tと改行との間)に動かします。

 
---------- Buffer: foo ----------
I read "∗The cat in the hat
comes back" twice.
---------- Buffer: foo ----------

(re-search-forward "[a-z]+" nil t 5)
     ⇒ 27

---------- Buffer: foo ----------
I read "The cat in the hat∗
comes back" twice.
---------- Buffer: foo ----------
Command: re-search-backward regexp &optional limit noerror repeat

この関数は、 カレント・バッファで正規表現regexpに一致するテキスト文字列を求め、 ポイントから逆方向に検索し、 見つかった最初の文字列の先頭にポイントを置きます。

この関数は、re-search-forwardと似ていますが、 単純な鏡像ではありません。 re-search-forwardは照合の開始が出発点になるべく近い箇所を見つけます。 もしre-search-backwardが完全な鏡像であれば、 照合の終了がなるべく近い箇所を見つけるでしょう。 しかしながら、これは照合の開始がなるべく近い箇所を見つけます。 この理由は、与えられた点からの正規表現の照合が常に先頭から末尾へ、 そして指定した先頭位置から開始するためです。

re-search-forwardの真の鏡像には、 末尾から先頭にregexpを照合させる特殊な機能が必要です。 これは面倒で実装するほどの価値はありません。

Function: string-match regexp string &optional start

この関数は、 string中で最初の正規表現regexpの一致開始場所の添字か、 一致しない場合nilを返します。 startが非nilの場合、 検索はstring中のその添字から行ないます。

たとえば、

 
(string-match
 "quick" "The quick brown fox jumped quickly.")
     ⇒ 4
(string-match
 "quick" "The quick brown fox jumped quickly." 8)
     ⇒ 27

文字列の最初の文字の添字は0で、 次の文字の添字は1、などなどとなります。

この関数が戻った後で、 一致部分を過ぎた最初の文字の添字は(match-end 0)で得られます。See section 一致データ

 
(string-match
 "quick" "The quick brown fox jumped quickly." 8)
     ⇒ 27

(match-end 0)
     ⇒ 32
Function: looking-at regexp

この関数は、 カレント・バッファ内のポイントの直後のテキストが正規表現regexpに 一致するか否かを調べます。 「直後」ということは、 検索が「固定」("anchor")され、 ポイントに続く最初の文字から一致が成功しなくてはいけない、 ということです。 そうなる場合、結果はtで、 そうならない場合nilになります。

ポイントは動かしませんが、 match-beginningmatch-endでアクセスできる一致データを 更新します。See section 一致データ

次の例において、ポイントは`T'の直前にあります。 別の場所に置かれていたとすると、結果はnilになったはずです。

 
---------- Buffer: foo ----------
I read "∗The cat in the hat
comes back" twice.
---------- Buffer: foo ----------

(looking-at "The cat in the hat$")
     ⇒ t

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.4 POSIX正規表現の検索

通常の正規表現の関数群は、 `\|'と繰り返しの構文要素を処理するために、 必要に応じバックトラックを行ないますが、 続行は少しでも一致が見つかる間だけでしかありません。 このとき関数は成功し最初の一致を返します。

この節では、正規表現照合のPOSIX標準で規定された 完全なバックトラックを行なう代替の検索関数について述べます。 これはすべての可能性を試し、 すべての一致を見つけるまでバックトラックを継続するので、 POSIXで要求されているように、最長の一致を報告することができます。 これはとても遅いので、 本当に最長の一致が必要なときだけこの関数を使うようにしてください。

Emacsバージョン19.29以前には、これらの関数はありません。 前述の関数が完全なPOSIXバックトラックを実装していました。

Function: posix-search-forward regexp &optional limit noerror repeat

これはre-search-forwardに似ていますが、 POSIX標準の正規表現照合で規定されている完全なバックトラックを行ないます。

Function: posix-search-backward regexp &optional limit noerror repeat

これはre-search-backwardに似ていますが、 POSIX標準の正規表現照合で規定されている完全なバックトラックを行ないます。

Function: posix-looking-at regexp

これはlooking-atに似ていますが、 POSIX標準の正規表現照合で規定されている完全なバックトラックを行ないます。

Function: posix-string-match regexp string &optional start

これはstring-matchに似ていますが、 POSIX標準の正規表現照合で規定されている完全なバックトラックを行ないます。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.5 検索と置換

Function: perform-replace from-string replacements query-flag regexp-flag delimited-flag &optional repeat-count map

この関数は、query-replaceや関連するコマンドの本体です。 これはfrom-stringの出現箇所を検索し、 一部あるいは全部を置換します。 もしquery-flagnilならば、すべての出現箇所を置換します。 そうでないとき、各出現箇所についてユーザにどうしたらいいか尋ねます。

もしregexp-flagが非nilならば、 from-stringは正規表現とみなします。 さもないと文字どおりの照合になります。 もしdelimited-flagが非nilならば、 語境界で囲まれた置換だけが対象になります。

引数replacementsは出現したものに置き換えるものを指定します。 もしこれが文字列なら、この文字列を使います。 文字列のリストの場合、これを周期的に使います。

もしrepeat-countが非nilならば、 整数でなければなりません。 このときreplacements中の次の文字列に進む前に、 各文字列を何回使うのかを指定します。

通常は、 キーマップquery-replace-mapが、 問い合わせにたいするユーザのとりうる反応を定義します。 引数mapが非nilならば、 query-replace-mapの代わりに使うキーマップとなります。

Variable: query-replace-map

この変数は、y-or-n-pmap-y-or-n-p同様、 query-replaceや関連する関数における ユーザの有効な反応を定義する特殊なキーマップです。 通常のそれと2点異なるところがあります。

次はquery-replace-mapで意味のある「バインド」です。 いくつかはquery-replace一族でのみ意味をもちます。

act

対象の動作をとります。すなわち「はい」の返事です。

skip

対象の動作をとりません。すなわち「いいえ」の返事です。

exit

今の問いに「いいえ」で答え、 以降の問いにもすべて「いいえ」で答えると仮定します。

act-and-exit

今の問いには「はい」で答え、 以降の問いにはすべて「いいえ」で答えると仮定します。

act-and-show

今の問いには「はい」で答えますが、結果を示します。 次の問いには進みません。

automatic

今の問いと以降の問いに「はい」で答え、 以降の対話は行ないません。

backup

以前、質問を行なった箇所に戻ります。

edit

通常とられる動作の代わりに、 再帰編集にはいって処理します。

delete-and-edit

対象のテキストを消去し、 それを置換する再帰編集にはいります。

recenter

ウィンドウの中央に寄せて再表示を行ない、 同じ問いを繰り返させます。

quit

ただちにとりやめます。 y-or-n-pと関連した関数だけがこの答えを使います。

help

ヘルプを表示して、再び尋ねます。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.6 一致データ

Emacsは、 正規表現の検索で見つけたテキストの開始と終了の位置をおぼえています。 これは、たとえば、Rmailメッセージの日付のような複雑なパターンの検索ができ、 そして、パターンの制御下にある一致の部分的取り出しができる、 という意味です。

一致データは通常、一番最後の検索だけを記憶するので、 後で参照する検索と一致データの利用の間で、 別な検索をしないように注意深く、 気を配らなければなりません。 中間の検索が避けられない場合、 上書きをされないように、 一致データの保存と復帰を前後で行なわなければなりません。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.6.1 単純な一致データのアクセス

この節では、直前の検索照合操作で何が一致したか見つけるための、 一致データの使い方を説明します。

一致テキストの全体と、 括弧でくくった特定の正規表現の部分式 (subexpression) とを求めることができます。 以下の関数のcount引数がどちらなのかを指定します。 もしcountが0ならば、一致全体を求めます。 もしcountが正ならば、どの部分式が必要かを指定します。

正規表現の部分式は、 エスケープした括弧`\(…\)'でくくることを思い出してください。 count番目の部分式は、 正規表現全体の先頭から`\('の出現順に数えます。 最初は1、次は2、などなどとなります。 正規表現だけに部分式があります。 単純な文字列検索で有効な情報は、一致全体です。

Function: match-string count &optional in-string

この関数は、最後の検索照合操作の一致テキストを文字列として返します。 もしcountが0ならば、テキスト全体を返し、 もしcountが正ならば、 count番目の括弧でくくった箇所に対応する部分正規表現を返します。 もしcountが範囲外の場合や部分式が一致しなかった場合、 値はnilです。

もしそのような最後の操作が文字列にたいするstring-matchの場合、 同じ文字列を引数in-stringとして渡さなければなりません。 そうでない場合、つまりバッファにたいする検索照合では、 in-stringを省略するかnilを与えなければなりません。 その際、match-stringを呼ぶときのカレント・バッファは、 検索照合を行なったバッファと同じくなるようにしてください。

Function: match-beginning count

この関数は、 最後の正規表現検索で一致したテキストやその部分式の開始位置を返します。

countが0の場合、 値はregexp全体に一致したテキストの開始位置です。 そうでない場合、 countは正規表現のどの部分式の開始位置を返すかを指定し、 関数の値は部分式への一致の開始位置です。

一致の起きなかった`\|'選択肢の内部の部分式にたいしての値は、 nilになります。

Function: match-end count

この関数は、match-beginningと似ていますが、 最後の正規表現検索で一致したテキストの開始位置ではなく、 終了位置を返します。

一致データの使用例です。コメントはテキスト中の位置を示します。

 
(string-match "\\(qu\\)\\(ick\\)"
              "The quick fox jumped quickly.")
              ;0123456789      
     ⇒ 4

(match-string 0 "The quick fox jumped quickly.")
     ⇒ "quick"
(match-string 1 "The quick fox jumped quickly.")
     ⇒ "qu"
(match-string 2 "The quick fox jumped quickly.")
     ⇒ "ick"

(match-beginning 1)       ; `qu'の一致は
     ⇒ 4                 ;   添字4から始まる。

(match-beginning 2)       ; `ick'の一致は
     ⇒ 6                 ;   添字6から始まる。

(match-end 1)             ; `qu'との一致は
     ⇒ 6                 ;   添字6で終る。

(match-end 2)             ; `ick'との一致は
     ⇒ 9                 ;   添字9で終る。

次の例において、ポイントは行頭に置かれています。 検索後のポイントは、スペースと語`in'との間になります。 一致全体の開始位置は、 バッファの9番目の文字(`T')であり、 最初の部分式の一致の開始位置は、 13番目の文字(`c')です。

 
(list
  (re-search-forward "The \\(cat \\)")
  (match-beginning 0)
  (match-beginning 1))
    ⇒ (9 9 13)

---------- Buffer: foo ----------
I read "The cat ∗in the hat comes back" twice.
        ^   ^
        9  13
---------- Buffer: foo ----------

(この場合では、返される添字はバッファ内位置です。 バッファの最初の文字は1になります。)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.6.2 一致したテキストの置換

この関数は、 最後の検索で一致したテキストをreplacementで置き換えます。

Function: replace-match replacement &optional fixedcase literal string

この関数は、 最後の検索で一致したバッファのテキスト(もしくはstring) をreplacementで置き換えます。

最後の検索をバッファで行なった場合、 stringにはnilを指定します。 このときreplace-matchはバッファを編集し置換を行ないます。 この関数は、ポイントを置換テキストの終りに置いて、 tを返します。

検索したのがバッファでなく文字列だった場合、 同じ文字列をstringに渡します。 するとreplace-matchは新しい文字列を構成してそれを返します。

fixedcaseが非nilの場合、 それで置き換えるテキストの大文字小文字の違いは変更しません。 そうでない場合、置き換えられるテキストのcapitalizationにしたがい、 置き換えるテキストを大文字小文字の間で変換します。 元のテキストがすべて大文字の場合、 置き換えるテキストを大文字に変換します。 もし元のテキストの最初の語が大文字で始まっている (capitalized)なら、 置き換えるテキストの最初の語を大文字で始め (capitalize)ます。 もし元のテキストが1語しかなく、その語が1文字の大文字であるなら、 replace-matchはこれをすべて大文字とは見ずに、 まず最初の語が大文字で始まっている (capitalized)とみなします。

もしcase-replacenilならば、 fixed-caseの値にかかわらず、 大文字小文字変換は行ないません。See section 検索と大文字小文字の区別

literalが非nilの場合、 大文字小文字の変更を生じうる点は除いてreplacementをそのまま挿入します。 もしこれが(デフォルト値の)nilで ある場合、文字`\'を特別扱いします。 もしreplacement`\'が現われる場合、 以下の列のいずれかの一部分でなくてはいけません。

`\&'

`\&'は、置き換えられたテキスト全体になります。

`\n'

nを数字とした`\n'は、 もとのregexpにおけるn番目の部分式と一致したテキストになります。 部分式とは`\(…\)'で区切られた正規表現のことです。

`\\'

`\\'は置換テキストの中で1個の `\'になります。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.6.3 一致データ全体のアクセス

関数match-dataset-match-dataは、 一度に一致データを読み書きできます。

Function: match-data

この関数は、 最後の検索が一致したテキストに関するすべての情報を含むリストを新しく返します。 要素0は、正規表現全体への一致の開始位置です。 要素1は、表現全体への一致の終了位置です。 次の二つの要素は、最初の部分式への一致の開始、 終了位置で、以下同様です。一般に要素 は(match-beginning n)に対応し、 は(match-end n)に対応します。

バッファにたいする一致の場合、全要素はマーカか nilで、 string-matchで文字列の一致をした場合、 全要素は整数かnilです (Emacsバージョン18やそれ以前のバージョンでは、整数0の場合をのぞき、 文字列にたいしてもマーカを使っていました)。

いつものように、 検索の呼出しとその検索の一致データをアクセスしようと しているmatch-dataの呼出しとの間に、 別の検索がはいり込むようなことがあってはいけません。

 
(match-data)
     ⇒  (#<marker at 9 in foo>
          #<marker at 17 in foo>
          #<marker at 13 in foo>
          #<marker at 17 in foo>)
Function: set-match-data match-list

この関数は、一致データを match-listの要素に設定します。 match-listは、 以前にmatch-dataの呼出しが返した値のリストでなくてはいけません。

もしmatch-listが存在しないバッファを参照していても、 エラーにはなりません。 一致データが、無害ではありますが、意味のないものになるだけです。

store-match-dataset-match-dataの別名です。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.6.4 一致データの保存と復帰

検索を行なうかもしれない関数を呼び出すとき、 もし前の検索の一致データを後で使うために保存したいなら、 その呼出しの前後で一致データの保存と復帰をする必要があるかもしれません。 次の例は、一致データの保存をしないために起きる問題を示しています。

 
(re-search-forward "The \\(cat \\)")
     ⇒ 48
(foo)                   ; 多分fooは、
                        ;   検索を行なう。
(match-end 0)
     ⇒ 61              ; 予期せぬ結果。48にあらず!

一致データの保存と復帰はsave-match-dataで行なうことができます。

Macro: save-match-data body…

この特殊形式は、前後で一致データの保存復帰を行ないつつ、 bodyを実行します。

set-match-datamatch-dataで 特殊形式save-match-dataをまねることができます。 これはEmacs 18でも動作するコードを書くとき便利です。 それには以下のようにします。

 
(let ((data (match-data)))
  (unwind-protect
      …   ; もとの一致データを変えてしまうかもしれない。
    (set-match-data data)))

プロセス・フィルター関数(see section プロセス・フィルタ関数)と プロセスの見張り(see section 監視関数: プロセスのステータス変化の検出)を実行するとき、 Emacsは自動的に一致データの保存と復帰を行ないます。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.7 検索と大文字小文字の区別

デフォルトでは、 Emacsにおける検索は検索対象のテキストにおける大文字小文字の区別は無視します。 `FOO'の検索を指示した場合、 `Foo'`foo'も照合の対象とみなします。 これはregexpそして特に文字集合 (での検索) にも適用します。 したがって`[aB]'は、 `a'にも`A'にも`b'にも`B'にも一致します。

この機能がいらないとき、 変数case-fold-searchnilにします。 そうすると、大文字小文字の違いを含め、 すべての文字が厳密に一致しなくてはいけなくなります。 これはバッファローカルな変数です。 この変数の変更は、カレント・バッファにたいしてのみ影響を及ぼします (See section バッファローカルな変数(紹介))。 そのかわりに、 まだcase-fold-searchを優先させていないバッファでのデフォルト値の、 default-case-fold-searchの値を変えることもできます。

ユーザ・レベルでの段階的検索機能では、 別な方法で大文字小文字の区別をしています。 小文字がきたときは両方を探しますが、 大文字がきたときは大文字だけしか探しません。 しかし、これはLisp関数の使う検索関数とは関係のないことです。

User Option: case-replace

この変数は、 置き換え関数で大文字小文字の違いを保存すべきか否かを定めます。 もし変数がnilならば、置き換えテキストをそのまま使います。 非nilの値は、 置き換えるテキストの大文字小文字を、 置き換えられるテキストにあわせて変換することを意味します。

関数replace-matchで 実際にこの変数が使われます。See section 一致したテキストの置換

User Option: case-fold-search

このバッファローカル変数は、 検索が大文字小文字の違いを無視すべきか否かを定めます。 もしこの変数がnilの場合、大文字小文字の違いを無視しません。 そうでない場合は違いを無視します。

Variable: default-case-fold-search

この変数の値は、 まだそれに優先させていないバッファ におけるcase-fold-searchのデフォルト値です。 これは(default-value 'case-fold-search)と同じです。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

30.8 編集用の標準正規表現

この節では、 編集上のある目的で使用される正規表現を保持する変数について述べます。

Variable: page-delimiter

これはページをわける行頭を示すregexpです。 デフォルト値は"^\014" (つまり"^^L"あるいは"^\C-l")です。 改ページ文字で始まる行と一致します。

次の二つの正規表現は、一致が常に行頭から始まると仮定すべき ではありません。 照合位置を固定するのに`^'を使うべきではありません。 段落コマンドは大体、行頭でだけ一致を検査するため`^'は余計です。 非0の左マージンがあるときは、 左マージン後から始まる場合の一致も受けつけるべきです。 この場合`^'は誤りでしょう。 しかし、左マージンがないモードでは、 `^'は無害です。

Variable: paragraph-separate

これは段落をわける行の先頭を示す正規表現です (これを変更する場合、paragraph-startも変更する必要があります)。 デフォルト値は左マージンの後にスペース、 タブ、改ページだけしかない行に一致する、 "[ \t\f]*$"です。

Variable: paragraph-start

段落を始めるかもしくは段落をわける行の先頭を示す正規表現。 デフォルト値は(左マージンの後に) スペース、タブ、改ページだけしかない行に一致する、 "[ \t\n\f]"です。

Variable: sentence-end

これは文末を示す正規表現です (段落の境界も、必ず文を終らせます)。 デフォルト値は

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

これは終止符、疑問符、感嘆符の後に省略可能な閉じ括弧、 そしてその後にタブ、スペース、改行がくるものです。

この正規表現の詳細については、複雑な正規表現の例を参照してください。


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Yasutaka SHINDOH on September, 29 2006 using texi2html 1.76.