正規表現

(gnujdoc による info の日本語訳)

正規表現の構文
==============

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

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

任意の2つの正規表現AとBを連結できます。その結果は、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つの正規表現AとBは、AかBのい
     ずれかに一致する文字列に一致する正規表現となる。

     したがって、`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'
     任意の単語構成文字に一致する。エディタの構文テーブルによってこの文
     字が決まる。*Note Syntax::。

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

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

`\SC'
     構文がCでない任意の文字に一致する。

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

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

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

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

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