Next: , Up: Syntax of Regexps   [Contents][Index]


33.3.1.1 正規表現内の特殊文字

以下は正規表現内で特別な文字のリストです:

.(Period)

これは改行を除く1文字にマッチする。結合を使用して‘a.b’のような正規表現を作成できる。これは‘a’で始まり‘b’で終わる3文字の文字列にマッチする。

*

これはそれ自身が構成要素ではない。これは前置された正規表現を可能な限り繰り返したものにマッチすることを意味する後置演算子である。したがって‘o*’は任意の個数の‘o’にマッチする(‘o’を含まない場合にもマッチする)。

*’は常に前置された表現の最小の表現に適用される。つまり‘fo*’は‘o’の繰り返しであり‘fo’の繰り返しではない。これは‘f’、‘fo’、‘foo’、...にマッチする。

マッチを行う処理は構成要素‘*’を、マッチングにより即座に見つけ得る回数分処理して、その後にパターンの残りを継続する。これが失敗したら残りのパターンのマッチが可能になるかもしれないという期待のもとに、‘*’の変更された構成のうちいくつかのマッチを破棄することによるバックトラッキングが発生する。たとえば文字列‘caaar’にたいして‘ca*ar’をマッチングすると、‘a*’はまず3つすべての‘a’へのマッチを試みる。しかし残りのパターンは‘ar’でありマッチ対象に残されているのは‘r’だけなのでこの試みは失敗する。‘a*’にたいする次の代替策は2つの‘a’だけへのマッチである。この選択では残りのregexpのマッチは成功する。

警告: ネストされた繰り返し処理は、それらが曖昧なマッチとなるような場合には無期限な長時間の実行となり得る。たとえば文字列‘xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz’にたいして正規表現‘\(x+y*\)*a’のマッチを試みると、それが最終的に失敗するまでに数時間を要す可能性がある。Emacsはその試みのいずれも機能しないと結論する前に、‘x’のグループ化のそれぞれを試みなければならない。さらに悪いことに‘\(x*\)*’は無数の方法でnull文字列にマッチ可能なので無限ループを引き起こす。これらの問題を避けるにはネストされた繰り返しがバックトラッキングでの組み合わせ爆発(combinatorial explosion)が発生しないことを確実にするために注意深くチェックすること。

+

これは‘*’のような後置演算子だが前置された表現に少なくとも1回マッチしなければならない点が異なる。たとえば‘ca+r’は文字列‘car’や‘caaaar’にマッチするが文字列‘cr’にはマッチせず、その一方で‘ca*r’はこれら3つすべての文字列にマッチする。

?

これは‘*’のような後置演算子だが前置された表現に1回、またはマッチしないかのいずれかでなければならない点が異なる。例えば‘ca?r’は‘car’と‘cr’にマッチするが他にはマッチしない。

*?’, ‘+?’, ‘??

演算子 ‘*’、‘+’、‘?’には“非欲張り(non-greedy)”な変種が存在する。これらの演算子が可能な最長の部分文字列(含まれる表現全体へのマッチと等しい)とマッチするのにたいして、非欲張りな変種は可能な最短の部分文字列(含まれる表現全体と等しい)にマッチする。

たとえば正規表現‘c[ad]*a’を文字列‘cdaaada’に適用すると文字列全体にマッチするが、正規表現‘c[ad]*?a’を同じ文字列に適用すると‘cda’だけにマッチする(ここでマッチが許された表現全体にたいする‘[ad]*?’の可能な最短マッチは‘d’)。

[ … ]

これは‘[’で始まり‘]’で終端される文字候補(character alternative)。もっとも単純なケースでは、この2つのカッコ(brackets)の間にある文字が、この文字候補がマッチ可能な文字。

したがって‘[ad]’は1つの‘a’と1つの‘d’の両方にマッチし、‘[ad]*’は‘a’と‘d’だけで構成された任意の文字列(空文字列を含む)にマッチする。つまり‘c[ad]*r’は‘cr’、‘car’、‘cdr’、‘caddaar’等にマッチする。

開始文字と終了文字の間に‘-’を記述することにより、文字候補内に文字範囲を含めることができる。つまり‘[a-z]’は小文字のASCIIアルファベット文字にマッチする。範囲は‘[a-z$%.]’のように個別の文字と自由に組み合わせることができる。これは任意のASCII小文字アルファベットと‘$’、‘%’、またはピリオドとマッチする。

case-fold-searchが非nilなら、‘[a-z]’は大文字アルファベットにもマッチする。‘[a-z]’のような範囲はそのlocaleの照合順に影響されず、常にASCII順のシーケンスを表すことに注意。

さらに通常のregexpスペシャル文字は文字候補内では特別ではないことにも注意。文字候補内部では‘]’、‘-’、‘^’という完全に異なる文字セットが特別に扱われる。

文字候補内に‘]’を含めるには、それを最初の文字にしなければならない。たとえば‘[]a]’は‘]’と‘a’にマッチする。‘-’を含めるには文字候補の最初または最後の文字として‘-’を記述するか、範囲の後に配置すること。つまり‘[]-]’は‘]’と‘-’の両方にマッチする(以下で説明するように、ここでは‘\’は特別ではないので、文字候補内に‘]’を含めるために‘\]’は使用できない)。

文字候補内に‘^’を含めるには先頭以外のいずれかの場所に置くこと。

ある範囲がユニバイト文字cで始まり、マルチバイト文字c2で終われば、その範囲は2つの部分に分割される。1つはユニバイト文字‘c..?\377’、もう1つはマルチバイト文字‘c1..c2’。ここでc1c2が属する文字セットの最初の文字。

文字候補には名前付き文字クラスも指定できる(Char Classesを参照)。これはPOSIXの機能である。たとえば‘[[:ascii:]]’は任意のASCII文字にマッチする。文字クラスの使用は、そのクラス内すべての文字を記述するのと等しい。しかし異なる文字を数千含むクラスもあるので、後者は実際は実現可能ではない。

[^ … ]

[^’は補完文字候補(complemented character alternative)を開始する。これは指定された以外の任意の文字とマッチする。つまり‘[^a-z0-9A-Z]’はアルファベットと数字以外の、すべての文字にマッチする。

^’は文字クラス内では先頭に記述されない限り特別ではない。‘^’に続く文字は、あたかもそれが先頭にあるかのように扱われる(言い換えると‘-’や‘]’はここでは特別ではない)。

マッチしない文字の1つとして改行が記述されていなければ、補完文字候補は改行にマッチできる。これはgrepのようなプログラム内でのregexpの扱いとは対照的である。

文字候補のように名前付き文字クラスを指定できる。たとえば‘[^[:ascii:]]’は任意の非ASCII文字にマッチする。Char Classesを参照のこと。

^

バッファーのマッチングの際には‘^’は空文字列、ただしマッチ対象のテキスト内にある行の先頭(またはバッファーのアクセス可能範囲の先頭)だけにマッチする。それ以外のマッチはすべて失敗する。つまり‘^foo’は行の先頭に出現する‘foo’にマッチする。

バッファーではなく文字列とマッチする際には、‘^’は文字列の先頭か改行文字の後にマッチする。

歴史的な互換性という理由により‘^’は正規表現の先頭、または‘\(’、‘\(?:’、‘\|’の後でのみ使用できる。

$

これは‘^’と似ているが、行の終端(またはバッファーのアクセス可能範囲の終端)だけにマッチする。つまり‘x+$’は行末にある1つ以上の‘x’からなる文字列にマッチする。

バッファーではなく文字列とマッチする際には、‘$’は文字列の終端か改行文字の前にマッチする。

歴史的な互換性という理由により‘$’は正規表現の先頭、または‘\(’、‘\(?:’、‘\|’の前でのみ使用できる。

\

これはスペシャル文字(‘\’を含む)のクォートと、追加のスペシャル文字の導入という2つの機能をもつ。

\’はスペシャル文字をクォートするので‘\$’は‘$’、‘\[’は‘[’だけにマッチする正規表現のようになる。

\’はLisp文字列(String Typeを参照)の入力構文(read syntax)内でも特別な意味をもち、‘\’でクォートしなければならないことに注意。たとえば文字‘\’にマッチする正規表現は‘\\’。文字‘\\’を含むLisp文字列を記述するには、別の‘\\’で‘\\’をクォートすることをLisp構文は要求する。したがって‘\’にマッチする正規表現にたいする入力構文は"\\\\"となる。

注意してください: 歴史的な互換性のために、スペシャル文字はそれらがもつ特別な意味が意味を成さないコンテキスト内にある場合には通常の文字として扱われます。たとえば‘*foo’は‘*’が作用可能な前置された表現がないので、通常の‘*’として扱われます。この挙動に依存するのは悪い習慣です。どこにそれが出現しようとスペシャル文字はすべてクォートしてください。

文字候補内で‘\’は何ら特別ではないので、‘-’や‘]’の特別な意味を取り除くことは決してありません。特別な意味をもたないような場合でも、これらの文字をクォートするべきではありません。バックスラッシュ以外の任意の1文字にマッチする‘[^\]’ (Lisp文字列構文では"[^\\]")内でのように、これらの文字が特別な意味をもつ箇所では、これらの文字にバックスラッシュを前置することには正当性があるので、何もそれほど明解にはしないでしょう。

実際には正規表現内に出現する‘]’は文字候補に近接しており、それ故そのほとんどがスペシャル文字です。しかしリテラルの‘[’と‘]’の複雑なパターンにたいしてマッチを試みることも時にはあるかもしれません。そのような状況では文字候補を囲う角カッコがどれなのかを判断するために、regexpを最初から注意深く解析することが必要なときもあるかもしれません。たとえば‘[^][]]’は補完文字候補‘[^][]’ (角カッコ以外の任意の1文字とマッチする)と、その後のリテラルの‘]’により構成されます。

厳密にはregexp先頭の‘[’は特別で、‘]’は特別ではないというのがルールです。これはクォートされていない最初の‘[’で終わり、その後は文字候補になります。(文字クラス開始を除き)‘[’はもはや特別ではありませんが、‘]’は直後にスペシャル文字‘[’があるか、その‘[’の後に‘^’がある場合を除いて特別です。これは文字クラス終了ではない次のスペシャル文字‘]’まで続きます。これは文字候補を終了させて、通常の正規表現の構文をリストアします。クォートされていない‘[’は再び特別となり、‘]’は特別ではなくなります。