Next: Search Case, Previous: Regexp Search, Up: Search
正規表現には、特別な使い方をする少数の文字と その他の普通の文字から成る構文があります。 普通の文字は、 同じ文字だけに一致してそれ以外には一致しない単純な正規表現です。 特別な文字は、‘$’、‘^’、‘.’、‘*’、‘+’、 ‘?’、‘[’、‘]’、および、‘\’です。 ‘\’が先行する場合を除いて、 正規表現に現れるこれら以外の文字は普通の文字です。
たとえば、‘f’は特別な文字ではなく、通常の文字ですから、 文字列‘f’に一致してそれ以外の文字列には一致しない正規表現です。 (これは、文字列‘ff’には一致しない。) 同様に、‘o’は、‘o’だけに一致する正規表現です。 (大文字小文字を区別しない場合、 これらの正規表現は‘F’や‘O’にも一致するが、 これらは例外というよりは、『同じ文字列』の一般化として捉える。)
任意の2つの正規表現aとbを連結できます。 その結果は、aが文字列の始めの適当な部分に一致して、かつ、 bが文字列の残りの部分に一致する場合に、 文字列に一致するような正規表現です。
簡単な例として、正規表現‘f’と‘o’を連結すると、 正規表現‘fo’を得ますが、 これは文字列‘fo’だけに一致します。 簡単ですね。 多少とも複雑なことを行うには、特別な文字を使う必要があります。 以下にその一覧をあげます。
‘*’はつねに先行する最小の正規表現に適用される。 したがって、‘fo*’は‘fo’を繰り返すのではなく、 ‘o’を繰り返す。 この正規表現は‘f’、‘fo’、‘foo’などに一致する。
‘*’を用いた構成は、一致を処理するときには、
ただちに得られる限りの反復回数に展開される。
そうしてから、残りのパターンを処理する。
一致に失敗すると、バックトラック(後戻り)が発生して、
‘*’を用いた構成の反復回数を減らして、
パターンの残りの部分が一致するようにする。
たとえば、文字列‘caaar’に対して
‘ca*ar’を一致させることを考えてみる。
始めに、‘a*’を3つの‘a’すべてに一致させようとする。
しかし、残りのパターンが‘ar’なのに‘r’しか残っていないため、
この試みは失敗する。
そこで、つぎは‘a*’を‘a’2つだけに一致させる。
こうすると、残りの正規表現も正しく一致する。
したがって、‘[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では変更するかもしれない。
‘^’は先頭になければ文字集合では特別な意味を持たない。 ‘^’に続く文字は先頭にあるものとして扱われる (いいかえれば、ここでは‘-’や‘]’は特別な意味を持たない)。
文字の補集合は、一致しない文字として改行を指定しない限り、改行にも一致する。
この点は、grep
のようなプログラムでの正規表現の扱い方と対照的。
‘\’は特別な文字をクォートするので、 ‘\$’は文字‘$’だけに一致する正規表現、 ‘\[’は文字‘[’だけに一致する正規表現、 というようになる。
注意: 従来との互換性のために、特別な文字が、 それらの特別な意味をなしえない文脈で使われた場合には、 普通の文字として扱われます。 たとえば、‘*foo’では、‘*’の対象となる正規表現が直前にないため、 ‘*’は普通の文字として扱われます。 このようなふるまいに依存することはよい習慣ではありません。 特別な文字を書く位置に関係なく特別な文字はクォートするべきです。
多くの場合、任意の文字を伴う‘\’はその文字だけに一致します。 しかし、いくつか例外があって、 ‘\’で始まる2文字列が特別な意味を持つ場合があります。 2文字目にくる文字は、 単独で使った場合には普通の文字として扱われるものです。 以下に‘\’の構成を列挙します。
したがって、‘foo\|bar’は、‘foo’か‘bar’に一致するが、 それ以外の文字列には一致しない。
‘\|’は、周囲にある適用しうる正規表現の中でも最大のものに適用される。 ‘\|’によるグループ化を制限するのは、 これを囲む‘\( ... \)’によるグループ化だけ。
何度‘\|’を使っても処理できるだけの十分なバックトラック能力がある。
最後の使い方は、括弧によるグループ化という考え方から
派生したものではない。
同一の‘\( ... \)’構成に与えた2つめの別の機能である。
実用上、これら2つの意味が混同されることはない。
一致を処理するときには、‘\( ... \)’構成の末尾に達すると、 この構成に一致したテキストの始めと終りを記録する。 そして、正規表現のそれよりうしろでは、 『d番目に現れた‘\( ... \)’に一致したテキスト』という意味で ‘\’に続けて数字dを使える。
1つの正規表現内に現れる最初の9個の‘\( ... \)’に一致する文字列には、 正規表現中で開き括弧が現れた順に、1から9までの番号を割りふる。 そのため、‘\1’から‘\9’で、 対応する‘\( ... \)’に一致したテキストを参照できる。
たとえば、‘\(.*\)\1’は、改行を含まない文字列で、かつ、 前半と後半が同一である文字列に一致する。 ‘\(.*\)’は前半部分に一致し、それはどのようなものでもかまわない。 一方、それに続く‘\1’は、 前半部分とまったく同じテキストに一致しなければならない。
ある‘\( ... \)’が、
(直後に‘*’がある場合などに簡単に起こりえる)
複数回一致する場合には、最後に一致したものだけを記録する。
‘\b’は、
バッファの先頭や末尾にあるテキストとは無関係に、
バッファの先頭や末尾にも一致する。
単語や構文に関連する構成要素は、 構文テーブル(see Syntax)の設定で制御されます。
複雑な正規表現を以下に示します。 これは、任意個の白文字がうしろに続く文末を認識するためにEmacsが使うものです。 空白とタブ文字を区別できるように、Lispの構文で示してあります。 Lisp構文では、文字列定数はダブルクォートで始まり、 ダブルクォートで終ります。 ‘\"’は正規表現の一部としてのダブルクォートを表し、 ‘\\’は正規表現の一部としてのバックスラッシュを表します。 ‘\t’はタブ文字、‘\n’は改行文字を表します。
"[.?!][]\"')]*\\($\\|\t\\| \\)[ \t\n]*"
この正規表現は4つの部分が繋がってできています。 ピリオド、‘?’、‘!’のいずれかに一致する文字集合。 閉じ中括、2種類の引用符、括弧に一致する文字集合の任意回数の繰り返し。 バックスラッシュ付きの括弧で括った、 行末、タブ、空白2つのいずれかに一致する選択肢。 白文字に一致する文字集合の任意回数の繰り返し。
これと同じ正規表現を対話的に入力するときには、 タブを入力するには<TAB>を打ち、 改行を入力するにはC-jを打ちます。 また、Lisp構文上ではバックスラッシュを2つ続けてますが、 対話的に入力するには、1つのバックスラッシュだけを打ちます。