##
4.2.1 正規表現のシンタックス

正規表現(すなわち RE)は、それとマッチする文字列の集合を指定します； このモジュールの関数によって、特別な文字列が与えられた正規表現と マッチするかどうか（あるいは与えられた正規表現が特別な文字列と マッチするかどうか、これは結局同じことになりますが）を検査できます。

正規表現は、連結して新しい正規表現を作ることができます； もし A と B が、ともに正規表現であれば、 AB も正規表現です。一般的には、もし文字列 p が A とマッチし、 別の文字列 q が B とマッチすれば、文字列 pqは AB にマッチ します。ただし、この状況が成り立つのは A や B が 優先度の低い演算や A と B との間の境界条件、あるいは 番号付けされたグループ参照を含まない場合だけです。 かくして、ここで述べるような、より簡単でプリミティブな正規表現から、 複雑な正規表現を容易に構築することができます、 正規表現に関する理論と実装の詳細については、上記の Friedl 本か、コンパイラー構造に関する大抵の教科書を調べて下さい。

以下で正規表現の形式に関する簡単な説明をしておきます。より詳細な情報や よりやさしい説明に関しては、http://www.python.org/doc/howto/からアクセスできる正規表現ハウツウを調べて下さい。

正規表現には、特殊文字と通常文字の両方を含めることができます。 "`A`"、 "`a`"、あるいは "`0`"のような 殆どの通常文字は、もっとも簡単な正規表現です；それらは、単純にそれら 自身とマッチします。通常文字を連結することもできますので、 `last` は文字列 `'last'`とマッチします。(このセクションの 残りでは、RE を普通引用符なしで `この特殊な形式`で書き、 マッチされる文字列は、`'単一引用符内'`に書きます。)

"`|`" や "`(`"のようないくつかの文字は特殊文字です。 特殊文字は通常文字クラスを表すか、あるいは通常文字に関する 正規表現がどのように解釈されるかに影響します。

特殊文字は：

"`.`"
  (ドット。) デフォールトのモードでは、これは改行以外の 任意の文字とマッチします。もし`DOTALL` フラグが指定されていれば、 これは、改行も含むすべての文字とマッチします。

"`^`"
  (キャレット。) 文字列の先頭と マッチし、`MULTILINE` モードでは、各改行の直後と マッチします。

"`$`"
  文字列の末尾、あるいは文字列の末尾の改行の 直前とマッチします。 `foo`は、'foo' と'foobar' の両方とマッチし、 一方、正規表現 `foo$`は、'foo' だけとマッチします。 もっと興味深いことは、'foo1\nfoo2\n' で `foo.$`を検索すると、 普通は 'foo2' とマッチするのですが、 `MULTILINE`モードでは 'foo1' とマッチします。

"`*`"
  結果の RE は、 前にある RE を、0 回以上できるだけ多く繰り返したものと マッチするようになります。`ab*` は、 'a'、'ab'、あるいは 'a' に任意個数の'b' を続けたものとマッチします。

"`+`"
  結果の RE は、 前にある RE を、1 回以上繰り返したものと マッチするようになります。`ab+` は、'a' に非ゼロ個の 'b' が 続いたものとマッチします；これは、'a' だけとはマッチしません。

"`?`"
  結果の RE は、 前にある RE を、0 回か 1回繰り返したものとマッチするようになります。 `ab?` は、'a' あるいは 'ab' とマッチします。

`*?`, `+?`, `??`
  "`*`"、 "`+`"、および "`?`" 修飾子は、すべて 欲張り(greedy)です； それらはできるだけ多くのテキストとマッチします。時にはこの動作が 望ましくない場合があります； もし RE `<.*>` を、 `'<H1>title</H1>'`とマッチさせると、これは、全文字列とマッチし、 `'<H1>'`だけとはマッチしません。"`?`"を修飾子の後に追加すると、 控え目な(non-greedy) あるいは 最小 風のマッチをするようになります； できるだけ 少ない 文字とマッチします。前の式で `.*?`を使うと、 `'<H1>'` だけとマッチします。

`{m}`
  前にある RE の m 回の正確なコピーとマッチすべきであることを指定 します；マッチ回数が少なければ、RE 全体ではマッチしません。例えば、 `a{6}` は、正確に 6個の "`a`" 文字とマッチしますが、 5個ではマッチしません。

`{m,n}`
  結果の RE は、前にある RE を、 m回からn 回まで繰り返したもので、 できるだけ多く繰り返したものとマッチするように、マッチします。 例えば、`a{3,5}`は、3個から 5個の "`a`" 文字とマッチします。 mを省略するとマッチ回数の下限として0を指定した事になり、 n を省略することは、上限が無限であることを指定します； `a{4,}b` は `aaaab`や、千個の "`a`" 文字に `b`が 続いたものとマッチしますが、`aaab`とはマッチしません。 コンマは省略できません、そうでないと修飾子が上で述べた形式と混同されてしまうからです。

`{m,n}?`
  結果の RE は、前にある RE の m回からn 回まで繰り返したもので、できるだけ少なく 繰り返したものとマッチするように、マッチします。これは、前の修飾子の 控え目バージョンです。 例えば、 6文字 文字列 `'aaaaaa'`では、`a{3,5}` は、5個の "`a`" 文字とマッチしますが、`a{3,5}?` は3個の文字と マッチするだけです。

"`\`"
  特殊文字をエスケープする( "`*`"や "`?`"等のような文字との マッチをできるようにする)か、あるいは、特殊シーケンスの合図です; 特殊シーケンスは後で議論します。

  もしパターンを表現するのに raw string を使用していないのであれば、 Python も、バックスラッシュを文字列リテラルでのエスケープシーケンスとして 使っていることを覚えていて下さい；もしエスケープシーケンスを Python の構文解析器が認識して処理しなければ、そのバックスラッシュと それに続く文字は、結果の文字列にそのまま含まれます。しかし、もし Python が 結果のシーケンスを認識するのであれば、バックスラッシュを 2回 繰り返さなければ いけません。このことは複雑で理解しにくいので、 最も簡単な表現以外は、 すべて raw string を使うことをぜひ勧めます。

`[]`
  文字の集合を指定するのに使用します。文字は個々に リストするか、文字の範囲を、2つの文字と"`-`"でそれらを分離 して指定することができます。特殊文字は集合内では有効ではありません。 例えば、`[akm$]`は、文字 "`a`"、"`k`"、 "`m`"、あるいは "`$`"のどれかとマッチします； `[a-z]` は、任意の小文字と、`[a-zA-Z0-9]` は、 任意の文字や数字とマッチします。 (以下で定義する) `\w` や`\S`のような 文字クラスも、範囲に含めることができます。もし文字集合に "`]`" や "`-`" を含めたいのなら、その前にバックスラッシュを 付けるか、それを最初の文字として指定します。たとえば、パターン `[]]` は `']'` とマッチします。

  範囲内にない文字とは、その集合の補集合をとることで マッチすることができます。これは、集合の最初の文字として "`^`" を含めることで表すことができます； 他の場所にある "`^`"は、単純に "`^`"文字とマッチするだけです。例えば、 `[^5]` は、 "`5`"以外の任意の文字とマッチし、 `[^`^`]` は、 "`^`" 以外の任意の文字とマッチします。

"`|`"
  `A|B` は、ここで A と B は任意の RE ですが、 A か B のどちらかとマッチする正規表現を作成します。任意個数の RE を、 こういう風に "`|`" で分離することができます。これはグループ (以下参照) 内部でも同様に使えます。検査対象文字列をスキャンする中で、 "`|`" で分離された RE は左から右への順に検査されます。 一つでも完全にマッチしたパターンがあれば、そのパターン枝が受理されます。 このことは、もし `A` がマッチすれば、たとえ`B` によるマッチが 全体としてより長いマッチになったとしても、`B` を決して検査しないことを 意味します。 言いかえると、"`|`" 演算子は決して貪欲 (greedy) ではありません。 文字通りの "`|`"とマッチするには、`\|` を使うか、 あるいはそれを `[|]` のように文字クラス内に入れます。

`(...)`
  丸括弧の中にどのような正規表現があってもマッチし、 またグループの先頭と末尾を表します；グループの中身は、マッチが 実行された後に検索され、後述する `\number` 特殊シーケンス付きの文字列内で、後でマッチされます。 文字通りの "`(`" や "`)`"とマッチするには、 `\(` あるいは `\)` を 使うか、それらを文字クラス内に入れます： `[(] [)]`。

`(?...)`
  これは拡張記法です( "`(`" に続く"`?`"は他には意味がありません)。 "`?`"の後の最初の文字が、この構造の意味とこれ以上の シンタックスがどういうものであるかを決定します。 拡張記法は普通新しいグループを作成しません； `(?P<name>...)`がこの規則の唯一の例外です。 以下に現在サポートされている拡張記法を示します。

`(?iLmsux)`
  ( 集合 "`i`"、"`L`"、 "`m`"、 "`s`"、"`u`"、"`x`" から1文字以上)。グループは空文字列ともマッチします；文字は、 正規表現全体の対応するフラグ (`re.I`、 `re.L`、 `re.M`、 `re.S`、 `re.U`、 `re.X` ) を設定します。 これはもしflag 引数を`compile()` 関数に渡さずに、そのフラグを正規表現の一 部として含めたいならば 役に立ちます。

  `(?x)` フラグは、式が構文解析される 方法を変更することに注意して下さい。 これは式文字列内の最初か、あるいは1つ以上の空白文字の後で使うべきです。 もしこのフラグの前に非空白文字があると、その結果は未定義です。

`(?:...)`
  正規表現の丸括弧の非グループ化バージョンです。 どのような正規表現が丸括弧内にあってもマッチしますが、 グループによってマッチされたサブ文字列は、 マッチを実行したあと検索されることも、あるいは後でパターンで 参照されることも できません。

`(?P<name>...)`
  正規表現の丸括弧と同様ですが、 グループによってマッチされたサブ文字列は、記号グループ名 nameを介してアクセスできます。グループ名は、正しい Python 識別子でなければならず、各グループ名は、正規表現内で一度だけ定義され なければなりません。記号グループは、グループに名前が付けられていない場合のように、 番号付けされたグループでもあります。そこで上の例で 'id'という名前がついた グループは、番号グループ 1 として参照することもできます。

  たとえば、もしパターンが `(?P<id>[a-zA-Z_]\w*)`であれば、このグループは、 マッチオブジェクトのメソッドへの引数に、 `m.group('id')` あるいは `m.end('id')`のような名前で、 またパターンテキスト内(例えば、 `(?P=id)`) や 置換テキスト内( `\g<id>`のように) で名前で参照することができます。

`(?P=name)`
  前に name と名前付けされたグループに マッチした、いかなるテキストにもマッチします。

`(?#...)`
  コメントです；括弧の内容は 単純に無視されます。

`(?=...)`
  もし `...`が次に続くものとマッチすればマッチしますが、 文字列をまったく消費しません。これは先読みアサーション(lookahead assertion)と呼ばれます。 例えば、`Isaac (?=Asimov)` は、`'Isaac '`に `'Asimov'`が続く場合だけ、`'Isaac '`とマッチします。

`(?!...)`
  もし `...` が次に続くものとマッチしなければマッチします。 これは否定先読みアサーション(negative lookahead assertion)です。例えば、 `Isaac (?!Asimov)`は、`'Isaac '` に `'Asimov'`が続かない場合のみマッチします。

`(?<=...)`
  もし文字列内の現在位置の前に、 現在位置で終わる `...` とのマッチがあれば、マッチします。 これは 肯定後読みアサーション(positive lookbehind assertion)と呼ばれます。 `(?<=abc)def` は、"`abcdef`" にマッチを見つけます、 というのは後読みが3文字をバックアップして、含まれているパターンと マッチするかどうか検査するからです。含まれるパターンは、 固定長の文字列にのみマッチしなければなりません、ということは、 `abc` や `a|b` は許されますが、 `a*` や `a{3,4}` は許されないことを意味します。 肯定後読みアサーションで始まるパターンは、検索される文字列の 先頭とは決してマッチしないことに注意して下さい； 多分、`match()` 関数よりは `search()`関数を使いたいでしょう：

      >>> import re
      >>> m = re.search('(?<=abc)def', 'abcdef')
      >>> m.group(0)
      'def'

  この例ではハイフンに続く単語を探します：

      >>> m = re.search('(?<=-)\w+', 'spam-egg')
      >>> m.group(0)
      'egg'

`(?<!...)`
  もし文字列内の現在位置の前に `...`との マッチがないならば、マッチします。これは 否定後読みアサーション(negative lookbehind assertion)と呼ばれます。 肯定後読みアサーションと同様に、含まれるパターンは固定長さの文字列だけに マッチしなければいけません。否定後読みアサーションで始まるパターンは、 検索される文字列の先頭とマッチすることができます。

特殊シーケンスは "`\`" と以下のリストにある文字から 構成されます。もしリストにあるのが通常文字でないならば、結果の RE は 2番目の文字とマッチします。例えば、 `\$` は文字 "`$`"とマッチします。

`\number`
  同じ番号のグループの中身とマッチします。 グループは1から始まる番号をつけられます。例えば、 `(.+) \1` は、`'the the'` あるいは `'55 55'`とマッチしますが、 `'the end'`とはマッチしません(グループの後のスペースに注意して下さい)。 この特殊シーケンスは最初の 99 グループのうちの一つとマッチするのに使うことが できるだけです。もし numberの最初の桁が 0 である、すなわち numberが 3 桁の8進数であれば、それはグループのマッチとは解釈されず、 8進数値 number を持つ文字として解釈されます。 文字クラスの "`[`"と "`]`"の中の数値エスケープは、文字として 扱われます。

`\A`
  文字列の先頭だけにマッチします。

`\b`
  空文字列とマッチしますが、単語の先頭か末尾の時だけです。 単語は英数字あるいは下線文字の並んだものとして定義されていますので、単語の末尾は 空白あるいは非英数字、非下線文字によって表されます。 `\b` は、`\w` と `\W`の間の境界として定義されているので、 英数字であると見なされる文字の正確な集合は、`UNICODE`と`LOCALE`フラグの 値に依存することに注意して下さい。 文字の範囲の中では、`\b` は、 Python の文字列リテラルと互換性を持たせるために、 後退(backspace)文字を表します。

`\B`
  空文字列とマッチしますが、それが単語の先頭あるいは末尾に ない時だけです。これは `\b`のちょうど反対ですので、 `LOCALE` と`UNICODE`の設定にも影響されます。

`\d`
  任意の十進数とマッチします；これは 集合 `[0-9]` と同じ意味です。

`\D`
  任意の非数字文字とマッチします；これは 集合 `[^0-9]`と同じ意味です。

`\s`
  任意の空白文字とマッチします；これは 集合 `[ \t\n\r\f\v]`と同じ意味です。

`\S`
  任意の非空白文字とマッチします；これは 集合 `[^ \t\n\r\f\v]` と同じ意味です。

`\w`
  `LOCALE` と`UNICODE` フラグが 指定されていない時は、任意の英数文字および下線とマッチします；これは、集合 `[a-zA-Z0-9_]`と同じ意味です。`LOCALE`が設定されていると、 集合 `[0-9_]` プラス 現在のロケール用に英数字として定義されている任意の 文字とマッチします。 もし `UNICODE` が設定されていれば、 文字 `[0-9_]` プラス Unicode 文字特性データベースで英数字として分類されて いるものとマッチします。

`\W`
  `LOCALE`と `UNICODE` フラグが 指定されていない時、任意の非英数文字とマッチします；これは 集合 `[^a-zA-Z0-9_]`と同じ意味です。 `LOCALE`が指定されていると、 集合 `[0-9_]`になく、 現在のロケールで英数字として定義されていない任意の文字とマッチします。 もし `UNICODE`がセットされていれば、これは `[0-9_]` および Unicode 文字特性データベースで 英数字として表されている文字以外のものとマッチします。

`\Z`
  文字列の末尾とのみマッチします。

Python 文字列リテラルによってサポートされている標準エスケープの ほとんども、正規表現パーザに認識されます：

    \a      \b      \f      \n
    \r      \t      \v      \x
    \\

8進エスケープは制限された形式で含まれています：もし第1桁が 0 であるか、もし8進3桁であれば、それは8進エスケープとみなされます。 そうでなければ、それはグループ参照です。