TIPS/正規表現/正規表現演算子の説明

Last-modified: 2006-11-21 (火) 12:48:54

TIPS/正規表現

正規表現演算子

各正規表現演算子の説明

.

任意のキャラクタ一文字とマッチします。処理系やオプション指定によって、これが改行にマッチするものとしないものがあります。POSIX 1003.2では改行にもマッチするように規定されているようです。

*

演算子の直前に置かれている部分正規表現の可能な限り大きい繰り返しにマッチします。繰り返しの回数は0回でもかまいません。例を挙げると、

 fo*は、foにもfooにもマッチしますし、f(oが一個もない)にもマッチします。一般的には
 (foo)*のように繰り返しの対象となるものは部分正規表現でも受け付けられますが、処理系によっては文字の繰り返ししか認めていないものもあります。

*?

 *と同様ですが、マッチングがものぐさ(non-greedy)に行われる点が異なります。 [#n27eb849]

+

\+

 *と似ていますが、直前にある部分正規表現の一回以上の繰り返しにマッチします。つまり、 wh+y という正規表現は、why や whhhyにはマッチしますが、*とは違って、 wyとはマッチしません。 \+は、GNU grepやGNU sedで用いられるこれと等価な演算子です。これは他の処理系では使えないでしょう。 [#s2d4443f]

+?

 +と同様ですが、マッチングがものぐさ(non-greedy)に行われる点が異なります。

?

\?

直前にある部分正規表現、もしくは空文字列にマッチします。 \?は、GNU grepやGNU sedで用いられるこれと等価な演算子です。これは他の処理系では使えないでしょう。

??

 ?と同様ですが、マッチングがものぐさ(non-greedy)に行われる点が異なります。

|

\|

これら二つの演算子は、選択を行なうためのものです。演算子の左右に置かれた部分正規表現のいずれかにマッチします。 ^X|0 は先頭にXがある文字列か、0を含む文字列にマッチします (^と|は両方とも正規表現演算子ですが、その優先順位は ^が上のため、このような解釈になります)。 \|は、GNU grepやGNU sedで用いられる等価な演算子です。これは他の処理系では使えないでしょう。

[char-list]

[]の中に置かれた文字のいずれかにマッチします。これはキャラクタクラスなどと呼ばれます。[ABC]という指定は、A, B, Cのいずれかにマッチします。連続したキャラクタ群を指定する場合、その群の先頭と終端を -で繋いだ形で指定することができます。たとえば、[ABCDEFG]は [A-G]と等価な指定です。ここでの順序はlocaleによって定められた順序に従います。あるlocaleでは[a-z]に大文字の大部分が含まれたりする場合があります。たとえば GNU/Linux の en_US localeでは、
a A b B c C d D ... x X y Y z Z という並びになります。

[の直後に^がきていた場合には意味が逆になり、指定したキャラクタ群の補集合、つまり []内に置かれた文字以外の文字にマッチするということになります。たとえば[^ABC]という正規表現は A, B, C 以外のキャラクタにマッチします。範囲指定の終端と始点を共有する[a-c-e]のような指定をしたときの動作は未定義です。

キャラクタクラスの中では多くのメタキャラクタがその意味を失います。特に、伝統的なegrepでは、[]の中では\によるエスケープも効きません (\自体もその特殊な意味を失ってしまう)。そういった場合に ]や^、-といった[]内で特殊な意味を持つキャラクタをクラスに含めたいときには []^-]のように記述します。つまり、^は [の直後以外に、]は[の直後(補集合を指定しているときには^の直後)に置き、-はリストの最後に置くというやり方を使います。

最近の処理系では\によるエスケープや\を使ったメタキャラクタ(\wや\sなど)が有効なものが多いようです。逆に、鬼車などでは[や-、]をキャラクタクラスに含めるときはそれらをエスケープすることが推奨されています。

鬼車(やSunのJavaの正規表現パッケージ)では、キャラクタクラスの集合演算が可能です。詳しくは 鬼車正規表現の文字集合の項を参照してください。

よくある勘違い
[^foo]bar という正規表現は、「fooではない文字列に続いてbarという文字列が続くもの」 ではありません。「fでもoでもない文字に続いてbarという文字列が続いたもの」です。[]で囲んだものが表しているのは文字列ではなく文字の集合(その中に含まれる/含まれない文字のどれか) だということに注意してください。

陥りやすい罠
[亜-腕]とか [弌-熙] とか [亜-熙]といったものは、それぞれ「JIS第一水準の範囲の漢字」や「JIS第二水準の漢字」、「漢字」を表すものとして使われることが多いものですが、 Unicodeをベースとしているシステムの場合 (5.8以降のuse encodingしたPerlなど)、このような表記をしても期待通りの動作をすることはありません。なぜなら、Unicode (or ISO 10646/JIS X 0221)では漢字の並べ方がこれまで用いられてきたJIS X 0208 のそれとは異なるためです。

(regexp)

\(regexp\)

(と)で囲むことにより、ある一部分の文字列や正規表現をひとまとめに扱うことができます。たとえば(bang)+という正規表現は、bangやbangbang、bangbangbang という文字列にマッチします。bang+としたときとどのように違うかを確かめてみてください。

\(\)は、sed、grep、ed等 BREで使用される書き方で、働きは()と同じですが、 BREでは後方参照を行うための指定にもなります。 GNU grepの-Eオプション指定時では()も同様の働きをしますが、POSIX 1003.2 で規定されているEREでは後方参照が使えるという記述はありません。

{n,m}

{n,}

{n}

\{n\}

\{n,\}

\{n,m\}

m、nにはそれぞれ数値が入ります。数字が nだけの場合は、ちょうどn回の繰り返しの指定になります。{n,}という形の場合ではn回以上の繰り返し、{n,m}では nは繰り返しの下限、mは上限の指定となります。たとえば{3,5}では(直前の正規表現の)3回から5回の繰り返しになります。ですから、

hel{3,5}oは helllo, hellllo, helllllo にマッチしますが、helloにはマッチしません。 \{\}はsed、grep等で使用される書き方で、働きは{}と同じです。

繰り返しの回数は処理系ごとに制限があります。最も厳しい場合で255回程度が最大値となります。あまり大きな数字は使えないと考えたほうが良いでしょう。また、負の数を指定することは許されません。最大値ですが、PerlやRuby1.8で32766、GNU grepやGNU sedで32767、 PCREで65535あたりです。(Pythonでは4294967295(32bitの無符号整数の最大値) まで可能?)

{m,n}?

{n,}?

{n}?

{m,n}等と同様ですが、マッチングがものぐさ(non-greedy)に行われる点が異なります。

^

文字列の先頭にマッチします。^cryptは cryptにマッチしますが、 encryptにはマッチしません。処理系やモードによっては文字列中の改行の直後(つまり行の始め)にもマッチします。

$

文字列の末尾にマッチします。たとえば go$はgoとマッチしますが、 goldにはマッチしません。処理系やモードによっては文字列中の改行の直前(つまり行の終わり)にもマッチします。これは「アンカー」であり、改行を表す文字そのものにマッチするのではないということに注意してください。

\<

\m,[[:<:]]

“単語”の先頭にマッチします。たとえば \<away は awayにマッチしますが、farawayにはマッチしません。

Tclでは\mまたは[[:<:]]を使います。

\>

\M,[[:>:]]

“単語”の末尾にマッチします。ですから、gnu\>はgnuにマッチしますが、cygnusにはマッチしません。

Tclでは\Mまたは[[:>:]]を使います。

[:classname:]

POSIX1003.2ではキャラクタクラス指定のときに、名前によるキャラクタークラスの指定ができるようになりました。現在決められているものとそれぞれ意味は次のようになっています。これらのほかにそのときのロカールによって、ロカール依存のキャラクタクラスが使える場合があります。

POSIXキャラクタクラス クラス名 意味
[:alnum:] アルファベットと(十進)数字
[:alpha:] アルファベット
[:blank:] 空白文字(スペース、タブ等)
[:cntrl:] 制御文字
[:digit:] 十進数字
[:graph:] 印字可能かつ表示可能な文字(スペースは印字可能だが表示可能ではない)
[:lower:] アルファベットの小文字
[:print:] 印字可能なキャラクタ(=制御文字以外のキャラクタ)
[:punct:] 句読点(通常の文字、数字、制御文字、スペースのいずれでもないキャラクター)
[:space:] スペース、タブ、改ページ
[:upper:] アルファベットの大文字
[:xdigit:] 十六進数字

これらは実際に使用するときには:lower:?のような形になります (ブラケットが二重になることに注意してください)。キャラクタークラスの名称は、Cライブラリ関数のisxxx(ここで、 xxxには上記のキャラクタークラスの名称が入ります)で識別されるのと同じ集合を表します。[^:alnum:]のような否定形を使える処理系もあります。

注意すべきこととして、これらが実際に使用時に表す文字集合は、その時点におけるロカール(locale)に影響される可能性があるということです。例えば、ASCIIの場合には [A-Z]と:upper:?、 [A-Za-z]と:alpha:?などはそれぞれまったく同じ集合を表しますが、非ASCII環境においては、[A-Z]がASCIIと同じ集合を表すのに対して、ウムラウトやアクサングラーブなどがついた文字が :...:?の方には含まれる可能性があります。 更に言えば、EBCDICなどの環境にあっては[A-Z]が正しく「AからZまでの大文字」という集合を表さない可能性があるのに対し、:upper:?はそうではありません。

Perl(5.6以降)および PCRE には[:word:] (単語構成文字にマッチ)があります。

幾つかのドキュメントで、[:blank:]がGNU拡張であるという記述がありますが、手元にあるPOSIX 1003.2のドキュメントには[:blank:]の項目があります。 また、LC_CTYPEの設定により任意のキャラクタクラスを認識するようにしても良いことになっています。

\w

“単語”を構成するキャラクタ、つまり文字と数字それにアンダースコアのいずれかにマッチします。これは:alnum:?と同じ意味になります。

\W

“単語”を構成するキャラクタ以外のキャラクタのいずれかにマッチします。これはこれは[^[:alnum:]](もしあれば^:alnum:)と同じ意味になります。

\b

\y

“単語”の先頭、あるいは末尾にマッチします。言い換えれば、 “語の区切り”とマッチするということです。たとえば \bball\bは、前後に空白のある ball にはマッチしますが、baseballにはマッチしません。

gawk 3.0.xでは、\bがバックスペースを表すエスケープシーケンスと衝突するため、この演算子は \y となっています。Tclでも\yを使います。

\B

\Y

“単語”の中にある空文字列にマッチします。例を挙げると、 \Bgnu\Bは cygnus にはマッチしますが、gnuにはマッチしません。

一部の実装を除き、"a "(aの後に空白二つ)が" \B "に マッチするようです(単語の境界にない空文字列にマッチ)。

Tclでは\Yを使用します。

\d

perl等で使用されるもので、[0-9]と同じ意味、つまり任意の十進数字とマッチします。

\D

\dと似ていますが、意味は[^0-9]、つまり十進数字以外の任意の一文字とマッチします。

\s

「空白」一文字とマッチする正規表現演算子です。

\S

「空白以外」の一文字とマッチする正規表現演算子です。

\C

常に「1バイト」にマッチします。

\X

基本文字に続く任意個の合成文字で表されるUnicodeキャラクタにマッチします。

\A

^と似た働きをしますが、大きな違いは ^が文字列中に埋め込まれた改行の直後にもマッチする場合があるのに対して、この演算子は常に文字列の先頭にのみマッチするということです。

\Z

$と似ていますが、異なるのは$が文字列中に埋め込まれた改行の直前にもマッチすることがあるのに対して、この演算子は基本的には文字列の末尾にのみマッチするという点です。ただし文字列の最後の文字が改行であるとき、\Zは最後の改行の直前にマッチします。したがって

  foo\Zは
  foo\n(ここで\nは埋め込みの改行)にはマッチしますが、
  foo\n\nにはマッチしません。

\z

Perl 5.005で導入されたもので、\Zと似ていますが、\Zが文字列末尾の改行の直前にもマッチするのに対して、この演算子は文字列の末尾にのみマッチするという点が異なります。

\G

文字列の先頭もしくは(グローバル指定時の)前のマッチが終了した位置にマッチします。

\`

バッファの先頭にマッチします。^は処理系によっては改行の直後にもマッチしますが、この演算子はそういった場所にはマッチしません。

\'

バッファの末尾にマッチします。$は処理系によっては改行の直前にもマッチしますが、この演算子はそういった場所にはマッチしません。

\1 \2 \3 \4 \5 \6 \7 \8 \9

これらはそれに先行して現れた\(\)(または())で囲まれた部分正規表現に実際にマッチしている文字列を表します。\に続く数字は、正規表現全体の中でそれが現れた順番を示します。たとえば\1は最初に現れた部分正規表現に対する参照であり、\7であれば七番目のものです。この指定は、Perl、Ruby、Tcl、PCREは九番目を越える指定が可能です。ただし、対応する部分正規表現があることが条件になります。また、数字部分が0で始まってはいけません。8進数値指定との区別がつかないためです (注: PythonとPCREも、99までの指定ができます)。たとえば \(abc|123\)def\1という正規表現では、 \1はabcか、123のいずれかになります。

Pythonでは、曖昧さをなくすために\g<num>という表記が使えます。Perlではブレースを使って${1}のようにします。

\

\は厳密には正規表現演算子ではありません。しかし、上述した正規表現演算子を文字そのものとして扱いたいような場合に、その前に\を置くことによって演算子の働きを抑制することができます。たとえば、\[は[というキャラクタそのものに対する指定であって、キャラクタクラスの始まりを示すものではありません。

[.string.]

[=char=]

[..]は collating symbol(照合シンボル)と呼ばれる演算子で、[.と.]に挟まれたキャラクタ列を一つの照合要素とみなすように指定します。たとえば [.ch.]+は c か h の(任意の組み合わせの)繰り返しではなく、 chchのような繰り返しにマッチします。一方[==]は equivalence class(等価クラス)と呼ばれるもので、 [=と=]の間にあるキャラクタと“等価”なキャラクタにマッチします。たとえば[=e=]としたときに、 è、 é、 ê、 ë といったものも含まれるという指定ができます。

現状では、Perl、PCREのように認識はするが動作はしないという実装が主流のようです(Tclでは使える?)。

glibcでもコードとしては入っているようです。どのように使えるのかは確かめていません。

(?# text)

正規表現中に置くコメントです。括弧内にあるものはマッチングには関係しません。

拡張モード時には、#から行末までがコメントになります。

(?imsx-imsx:pattern)

(?imsx-imsx)

正規表現のオプションを指定します。これを使うことによってオプションを以降の正規表現に部分的に適用することが可能となります。 i,s,m,xはそれぞれ独立に使用できます。-が先行している場合にはそのオプションを打ち消す意味になります。(?:)はそのかっこに囲まれた範囲に影響が限定されます。前者では以降のすべてに影響が及びます (このオプション指定が存在していない処理系もあります。詳細は処理系のドキュメントを参照してください)。 Rubyではsオプションはありません。またmオプション指定時の動作は改行が'.'にマッチするようになります。 i,s,m,xのそれぞれの意味は以下のとおり。シングルラインモードおよびマルチラインモードについての詳細はそれぞれの処理系のドキュメントを参照してください。

正規表現修飾子の意味 修飾子 意味
i 大小文字の違いを無視する
s シングルラインモードにする(.が改行にマッチする)
m マルチラインモードにする(^と$が改行の直前直後にマッチ)
x 拡張表記を許可する

Pythonにはロカール依存を有効にするL修飾子と \w, \W, \b, \B の意味をUnicode のキャラクタプロパティに基づいたものにする u修飾子があります。

PCREには通常のマッチとものぐさマッチの指定とを逆転する(?U) オプションとPCRE_EXTRAモードを有効にする(?X)オプションがあります。PCRE_EXTRA モードでは、定義されていないバックスラッシュシーケンスがエラーになります。

Pythonで使用できる正規表現修飾子は下表のとおりです。

Pythonの正規表現修飾子の意味 修飾子対応するオプション意味 iIGNORECASE (I)大小文字の違いを無視する mMULTILINE (M)マルチラインモードにする(^と$が改行の直前直後にマッチ) sDOTALL (S)“.”が改行文字にマッチ xVERBOSE (X)拡張表記を許可する uUNICODE (U)\w \W \b \BがUnicodeの英数定義に従う lLOCALE (L)\w \W \b \Bがカレントのロカールでの英数定義に従う
Rubyで使用できる正規表現修飾子は下表のとおりです。

Rubyの正規表現修飾子の意味 修飾子対応するオプション意味 iRegexp::IGNORECASE大小文字の違いを無視する mRegexp::MULTILINEマルチラインモードにする(^と$が改行の直前直後にマッチ) xRegexp::EXTENDED拡張表記を許可する
.NET Frameworkで使用できる正規表現修飾子は下表の通りです。

.NETの正規表現修飾子の意味 修飾子 対応するオプション 意味
i RegexOptions.IgnoreCase 大小文字の違いを無視する
s RegexOptions.Singleline シングルラインモードにする(.が改行にマッチする)
m RegexOptions.Multiline マルチラインモードにする(^と$が改行の直前直後にマッチ)
n RegexOptions.ExplicitCapture (?...) で陽に名前付けまたは番号付けしたグループだけを有効なキャプチャにするように指定する。
x RegexOptions.IgnorePatternWhitespace 拡張表記を許可する

Javaのjava.util.regexで使用できる正規表現修飾子は下表の通りです。

Javaの正規表現修飾子の意味 修飾子 対応するオプション 意味
i CASE_INSENSITIVE 大小文字の違いを無視する
d UNIX_LINES Unixラインモードにする
s DOTALL シングルラインモードにする(.が改行にマッチする)
m MULTILINE マルチラインモードにする(^と$が改行の直前直後にマッチ)
u UNICODE_CASE Unicodeに準拠した大小文字を区別しないマッチングを指定する
x COMMENTS 拡張表記を許可する

(?:regexp)

部分正規表現のグルーピングを行いますが、 \( \)や()とは異なり後方参照を行うことはできません。たとえば、 foo(?:bar)baz はfoobarbazという文字列にマッチしますが、 foo(bar)bazの場合とは異なり、\1(またはそれに相当するもの)にはなにもセットされません。

(?=regexp)

括弧内にある正規表現が続くことを要求する表明です。マッチの結果の文字列には影響しません。例えば、else(?= if)という正規表現は “else if” にマッチしますが、Perlの$&のような正規表現全体にマッチした文字列は “else”となります(当然ながら、“ if”が後続していない “else”にはマッチしません)。

よくある勘違い
(?=foo)bar のように記述しても、「fooのあとにbarが続いている文字列」には なりません。 fooを先読みしてマッチのポイントは動かしませんので(それが先読みだから)、その場所にbarがあるかどうかで判断します。マッチのポイントより前にある文字列が存在するかどうかという判定ではありません (それをするのは戻り読み)。

(?!regexp)

(?=regexp)と似ていますが、こちらは括弧内にある正規表現が続かないことを要求する表明です。

肯定先読み と同様に、「ある文字列が先行していない文字列にマッチ」させるためにこの表明を使うことはできません。

(?<=pattern)

括弧内にある正規表現が先行していることを要求する表明です。マッチの結果の文字列には影響しません。例えば、(?<=\t)\wという正規表現はタブに続く単語にマッチしますが、マッチした文字列全体を表す $&(Perlの場合)にはタブは含まれません。後読み (もしくは戻り読み (lookbehind))は固定長の文字列に対してのみ働きます(処理系による。可変長の文字列を許可する処理系もあります→ 詳細)。

(?<!pattern)

括弧内にある正規表現が先行していないことを要求する表明です。マッチの結果の文字列には影響しません。例えば、(?<=foo)barという正規表現はfooが先行しないbarにマッチしますが、マッチした文字列全体を表す $&(Perlの場合)には fooは含まれません。後読み(もしくは戻り読み (lookbehind))は固定長の文字列に対してのみ働きます(処理系による。可変長の文字列を許可する処理系もあります)。

(?>pattern)

一旦マッチした部分正規表現をバックトラックすることのないパターンです。したがって、(?>a+)abは何にもマッチしません。カッコ内のパターンがすべてのaを消費し、それを手放さないためです。

(?(condition)yes-pattern|no-pattern)

(?(condition)yes-pattern)

条件式です。(condition)は、括弧の中に置かれた整数(対応するかっこのペアがマッチしているときに正当)もしくは長さゼロの lookahead/lookbehind/evaluate 表明であることが望ましいです。

Pythonでは表明は使えません。.NETでは名前による後方参照の指定ができます。

(?{ code })

Perlにおいて、埋め込まれたPerlコードを実行します

(??{ code })

Perlにおいて、埋め込まれたPerlコードを実行してその結果を正規表現を表すものとして使用します。

*+

 *に似ていますが、決してバックトラックしません。 [#nbbc0e75]

++

 +に似ていますが、決してバックトラックしません。

?+

 ?に似ていますが、決してバックトラックしません。

{n,m}+

{n,}+

{n}+

{n,m}等に似ていますが、決してバックトラックしません。

(?P<name>...)

(?<name>...) (?'name'...)

マッチした文字列を name という名前で参照できるようにします。

(?<name>...) や (?'name'...)は .NETで使用される表現です

(?P=name), \g<name>

\k<name> \k'name'

対応する(?P<name>...) でキャプチャした文字列を参照します。\g<name> は置換テキスト中で使う表現です。

\k<name> や \k'name'は .NETで使用される表現です(\k<name>は Ruby1.9.0でも使用可)。

(?P>name)

対応する(?P<name>...) でキャプチャした文字列を参照します。PCREの再帰的表現で使用します。以下に使用例を挙げます。バランスの取れた括弧の対にマッチします。

   (?P<pn>\(((?>[^()]+)|(?P>pn))*\))(?<name1-name2>)

グループ定義を均等化します。既に定義されていたグループ name2 の定義を削除し、既に定義されていた name2 グループと現在のグループの間隔をグループ name1 に格納します。グループ name2 が定義されていない場合、一致はバックトラックされます。name2 の最後の定義を削除すると、name2 の以前の定義がわかるため、この構成体によって、かっこなど入れ子になった構成体を追跡するカウンタとしてグループ name2 のキャプチャのスタックを使用できます。この構成体では、name1 は省略できます。たとえば (?'name1-name2') のように、山かっこの代わりに一重引用符を使用することもできます。 (グループ化構成体より)

(?R)

PCREで、再帰的にパターンにマッチする表現です。

(?num)

PCREで、再帰的にパターンにマッチする表現です。 (?R)に似ていますが、こちらはパターン全体ではなくnumに対応するキャプチャされた部分正規表現が再帰の対象です。この例もバランスの取れた括弧の対にマッチします。

   (\()?[^()]+(?(1)\))次のような使い方もできます。
   (sens|respons)e and (?1)ibilityこれは \1 を使ったものとは異なり、sense and responsibility にもマッチします。

(?(R)...)

PCREで、再帰的パターンの開始を示します。

   <(?:(?(R)\\d++|[^<>]*+)|(?R))*>\p{name}, \P{name}

ブレースに囲まれた名前で指定されたキャラクタ集合に属するキャラクタを指定します。指定できるキャラクタ集合は一般に、Unicodeのプロパティ、スクリプト、ブロック、カテゴリです。処理系によっては使える集合が制限されていたりします。

各エスケープシーケンスの説明

\a

警告(ベル)です。

\b

バックスペースを表しますが文字クラス内に制限される処理系があります。

\e

エスケープ文字。Perl、PCREで使えます。

\n

改行。

\r

キャリッジリターン。

\f

改ページ。

\t

水平タブです。

\octal

2~3桁の8進表現文字です。数値が3桁ない場合0を数値に前置します (後方参照と区別するため)。

\xhex

\xxxx

16進表現文字です。何桁の表記か可能かどうかが処理系によって異なる場合があります (1桁でも可とか)。

\x{hex}

Perl等で使えるもので任意長の16進表現文字です。

\cchar

Perl等で使えるもので、制御キャラクタをあらわします。例えば \ci は水平タブになります。

注\c[ や \c\ はそのままでは記述できない場合があります。文字クラスの中に入れたり、\c\\のようにすることで回避できる場合があります。

\C-char

Rubyで使えるもので、制御キャラクタをあらわします。例えば \C-jは改行コードになります。

\M-char

Rubyで使えるもので、charと\x80をbitwise or したコードになります。例えば \M-@ は\xc0と等価です。Emacsでいうところのメタな文字です(正規表現のメタキャラクタと混同しないように)。

\uhhhh

\Uhhhhhhhh
Pyhton、Tcl等で使えるもので、それぞれ四桁、八桁の16進数表現文字です。Perlでは\u、\U とも別の意味があります。

\N{name}

Perl、Pythonで使えるもので名前付けられたキャラクタを表します。詳しくは charnamesを参照してください。