正規表現 HOWTO
**************

著者:
   A.M. Kuchling <amk@amk.ca>


概要
^^^^

このドキュメントは "re" モジュールを使って Python で正規表現を扱うため
の導入のチュートリアルです。ライブラリレファレンスの正規表現の節よりも
やさしい入門ドキュメントを用意しています。


はじめに
========

正規表現 regular expressions (REs や regexes または regex patterns と
呼ばれます) は本質的に小さく、Python 内部に埋め込まれた高度に特化した
プログラミング言語で "re" モジュールから利用可能です。この小さな言語を
利用することで、マッチさせたい文字列に適合するような文字列の集合を指定
することができます; この集合は英文や e-mail アドレスや TeX コマンドな
ど、どんなものでも構いません。「この文字列は指定したパターンにマッチし
ますか?」「このパターンはこの文字列のどの部分にマッチするのですか?」と
いったことを問い合わせることができます。正規表現を使って文字列を変更し
たりいろいろな方法で別々の部分に分割したりすることもできます。

正規表現パターンは一連のバイトコードとしてコンパイルされ、C で書かれた
マッチングエンジンによって実行されます。より進んだ利用法では、エンジン
がどう与えられた正規表現を実行するかに注意することが必要になり、高速に
実行できるバイトコードを生成するように正規表現を書くことになります。こ
のドキュメントでは最適化までは扱いません、それにはマッチングエンジンの
内部に対する十分な理解が必要だからです。

正規表現言語は相対的に小さく、制限されています、そのため正規表現を使っ
てあらゆる文字列処理作業を行なえるわけではありません。正規表現を使って
行うことのできる作業もあります、ただ表現はとても複雑なものになります。
それらの場合では、Python コードを書いた方がいいでしょう; Python コード
は念入りに作られた正規表現より遅くなりますが、おそらくより読み易いでし
ょう。


単純なパターン
==============

まずはできるだけ簡単な正規表現を学ぶことから始めてみましょう。正規表現
は文字列の操作に使われるので、ますは最も一般的な作業である文字のマッチ
ングをしてみます。

正規表現の基礎を成す計算機科学 (決定、非決定有限オートマトン) の詳細な
説明については, コンパイラ作成に関するテキストブックをどれでもいいので
参照して下さい。


文字のマッチング
----------------

多くの活字や文字は単純にそれ自身とマッチします。例えば、 "test" という
正規表現は文字列 "test" に厳密にマッチします。(大文字小文字を区別しな
いモードでその正規表現が "Test" や "TEST" にも同様にマッチすることもで
きます; 詳しくは後述します。)

この規則には例外が存在します; いくつかの文字は特別な *特殊文字
(metacharacters)* で、それら自身にマッチしません。代わりに通常のマッチ
するものとは違うという合図を出したり、正規表現の一部に対して繰り返した
り、意味を変えたりして影響を与えます。このドキュメントの中の多くは様々
な特殊文字とそれが何をするかについて論じることになります。

ここに特殊文字の完全な一覧があります; これらの意味はこの HOWTO の残り
の部分で説明します。

   . ^ $ * + ? { } [ ] \ | ( )

最初に扱う特殊文字は "[" と "]" です。これらは文字クラスを指定します、
文字クラスはマッチしたい文字の集合です。文字は個別にリストにしても構い
ませんし、二つの文字を "'-'" でつなげて文字を範囲で与えてもかまいませ
ん。たとえば "[abc]" は "a", "b", または "c" のどの文字列にもマッチし
ます; これは "[a-c]" で同じ文字集合を範囲で表現しても全く同じです。小
文字のアルファベットのみにマッチしたい場合、 "[a-z]" の正規表現をつか
うことになるでしょう。

("\" を除く) 特殊文字は文字クラスの内部では有効になりません。例えば、
"[akm$]" は "'a'", "'k'", "'m'", または "'{TX-PL-LABEL}#x27;" のいずれ
かにマッチします; "'{TX-PL-LABEL}#x27;" は通常は特殊文字ですが、文字ク
ラス内部ではその特別な性質は取り除かれます。

*補集合を取る* ことで、文字クラス内のリストにない文字に対してマッチさ
せられます。 補集合は、クラスの最初の文字として "'^'" を含めることで表
せます。 例えば、 "[^5]" は "'5'" 以外の文字にマッチします。 キャレッ
トが文字クラス以外の場所に現れた場合は、特別な意味は持ちません。 例え
ば、 "[5^]" は "'5'" や "'^'" にマッチします。

おそらく最も重要な特殊文字はバックスラッシュ "\" でしょう。 Python の
文字列リテラルのようにバックスラッシュに続けていろいろな文字を入力する
ことでいろいろな特殊シーケンスの合図を送ることができます。また、バック
スラッシュはすべての特殊文字をエスケープするのにも利用されます、つまり
、特殊文字をマッチさせることができます; 例えば、 "[" または "\" にマッ
チさせたい場合、それらをバックスラッシュに続けることで特殊な意味を除き
ます: "\[" または "\\" 。

"'\'" で始まるいくつかの特殊シーケンスは、数字、アルファベット、空白文
字以外など、よく使う文字集合を表しています。

一つ例をお見せしましょう: "\w" は任意の英数字文字にマッチします。バイ
ト列パターンに対しては、これは文字クラス "[a-zA-Z0-9_]" と等価です。ユ
ニコードパターンに対しては、 "\w" は "unicodedata" モジュールで提供さ
れている Unicode データベースで letters としてマークされている全ての文
字とマッチします。正規表現のコンパイル時に "re.ASCII" フラグを与えるこ
とにより、 "\w" を、より制限された定義で使うことが出来ます。

以下に続く特別な文字列のリストは完全ではありません。特殊シーケンスと拡
張クラスについてのユニコードパターンの定義についての完全なリストは、標
準ライブラリリファレンスの 正規表現の構文 の最後のパートを参照してくだ
さい。一般的にユニコードバージョンは、ユニコードデータベース内で相応し
いカテゴリに属すればマッチします。

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

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

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

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

"\w"
   任意の英数文字および下線とマッチします; これは、集合 "[a-zA-Z0-9_]"
   と同じ意味です。

"\W"
   任意の非英数文字とマッチします; これは集合 "[^a-zA-Z0-9_]" と同じ意
   味です。

これらのシーケンスは文字クラス内に含めることができます。例えば、
"[\s,.]" は空白文字や "','" または "'.'" にマッチする文字クラスです。

この節での最後の特殊文字は "." です。 これは改行文字を除く任意の文字に
マッチし、さらに改行文字に対してもマッチさせる代替モード ("re.DOTALL")
があります。 "." は「任意の文字」にマッチさせたい場合に利用されます。


繰り返し
--------

さまざまな文字集合をマッチさせることは正規表現で最初にできるようになる
ことで、これは文字列に対するメソッドですぐにできることではありません。
しかし、正規表現がより力を発揮する場面がこれだけだとすると、正規表現は
あまり先進的とはいえません。正規表現の力をもう一つの能力は、正規表現の
一部が何度も繰り返されるようものを指定できることです。

最初にとりあげる繰り返しのための最初の特殊文字は "*" です。 "*" は文字
リテラル "'*'" とはマッチしません; その代わりに、前の文字がぴったり1回
ではなく0回以上繰り返されるパターンを指定します。

例えば、 "ca*t" は "'ct'" (文字 "'a'" が 0 個)、 "'cat'" ("'a'" が 1
個)、 "'caaat'" ("'a'" が 3 個)、などにマッチします。

"*" のような繰り返しは *貪欲 (greedy)* です; 正規表現を繰り返したいと
き、マッチングエンジンは可能な限り何度も繰り返そうと試みます。パターン
の後ろの部分にマッチしない場合、マッチングエンジンは戻ってより少ない繰
り返しを再び試みます。

一歩ずつ例を進めていくとより明確にわかります。 正規表現 "a[bcd]*b" を
考えましょう。 この正規表現は文字 "'a'" 、文字クラス "[bcd]" の 0 個以
上の文字、最後に来る "'b'" にマッチします。 この正規表現が文字列
"'abcbd'" に対してマッチする流れを想像してみましょう。

+--------+-------------+-----------------------------------+
| ステッ | マッチした  | 説明                              |
| プ     | 文字列      |                                   |
|========|=============|===================================|
| 1      | "a"         | 正規表現の "a" がマッチ。         |
+--------+-------------+-----------------------------------+
| 2      | "abcbd"     | 正規表現エンジンが、文字列の終わ  |
|        |             | りに向かってできるだけ遠くまで    |
|        |             | "[bcd]*" をマッチさせる。         |
+--------+-------------+-----------------------------------+
| 3      | *失敗*      | 正規表現エンジンが "b" でマッチを |
|        |             | 試みるが、現在の位置が文字列の最  |
|        |             | 後な ので失敗。                   |
+--------+-------------+-----------------------------------+
| 4      | "abcb"      | "[bcd]*" が一文字少なくマッチする |
|        |             | ように戻る。                      |
+--------+-------------+-----------------------------------+
| 5      | *失敗*      | 再び "b" にマッチするか試みるが、 |
|        |             | 現在の位置は最後の文字 "'d'" 。   |
+--------+-------------+-----------------------------------+
| 6      | "abc"       | "[bcd]*" は "bc" のみにマッチする |
|        |             | ように再び戻る。                  |
+--------+-------------+-----------------------------------+
| 6      | "abcb"      | 再び "b" を試みる。今回の現在位置 |
|        |             | の文字は "'b'" なので成功。       |
+--------+-------------+-----------------------------------+

正規表現の終端に達して、 "'abcd'" にマッチしました。 この説明は、マッ
チングエンジンが最初に到達できるところまで進みマッチしなかった場合、逐
次戻って再度残りの正規表現とのマッチを次々と試みること様子を示していま
す。 正規表現エンジンは "[bcd]*" の 0 回マッチを試すところまで戻り、そ
の後続の正規表現とのマッチに失敗した場合には、エンジンは正規表現と文字
列が完全にマッチしないと結論づけることになります。

別の繰り返しのメタ文字には "+" があり、この特殊文字は 1 回以上の繰り返
しにマッチします。 "*" と "+" に違いに対しては十分注意して下さい; "*"
は *0 回* 以上の繰り返しにマッチするので、繰り返す部分が全くなくても問
題ありません。一方で "+" は少なくとも *1 回* は表われる必要があります
。 同様の例を使うと "ca+t" は "'cat'" ("'a'" 1 文字)、 "'caaat'"
("'a'" 3 文字)、とマッチし、"'ct'" とはマッチしません。

繰り返しをあらわす演算子または数量子がさらに2つ存在します。クエスチョ
ンマーク "?" は1回または0回の繰り返しにマッチします; これは、何らかの
文字やパターンがオプションであることをあらわすと考えられます。例えば、
"home-?brew" は "'homebrew'" と "'home-brew'" のいずれかにマッチします
。

最も複雑な数量子は "{m,n}" でしょう。ここで *m* と *n* は10進数の整数
です。この数量子は繰り返しの回数が最小で *m* 回、最大で *n* 回であるこ
とを意味します。例えば、 "a/{1,3}b" は "'a/b'", "'a//b'", および
"'a///b'" にマッチします。一方でスラッシュのない "'ab'" やスラッシュが
4つある "'a////b'" にはマッチしません。

*m* か *n* のどちらかは省略することができます; その場合は、省略された
値は合理的な値が仮定されます。 *m* の省略は下限は 0 と解釈され、*n* の
省略は上限は無限として解釈されます。

The simplest case "{m}" matches the preceding item exactly *m* times.
For example, "a/{2}b" will only match "'a//b'".

還元主義的傾向のある読者は、他の3つの数量子が全てこの表記を使って表現
できることに気づくでしょう。 "{0,}" は "*" と同じであり、 "{1,}" は
"+" と等価です。また "{0,1}" は "?" と同じです。とはいえ、簡潔さと読み
やすさの観点から、可能であれば "*", "+", "?" を使う方が望ましいです。


正規表現を使う
==============

これまででいくつかの単純な正規表現に触れてきました、実際に Python では
これらをどう使えばいいのでしょう? "re" モジュールは正規表現エンジンに
対するインターフェースを提供していて、それらを使うことで正規表現をオブ
ジェクトにコンパイルし、マッチを実行することができます。


正規表現をコンパイルする
------------------------

正規表現はパターンオブジェクトにコンパイルされます、パターンオブジェク
トは多くの操作、パターンマッチの検索や文字列の置換の実行などのメソッド
を持っています。

   >>> import re
   >>> p = re.compile('ab*')
   >>> p
   re.compile('ab*')

"re.compile()" はいくつかの *flags* 引数を受け付けることができます、こ
の引数はさまざまな特別な機能を有効にしたり、構文を変化させたりします。
利用できる設定に何があるかは後に飛ばすことにして、簡単な例をやることに
しましょう:

   >>> p = re.compile('ab*', re.IGNORECASE)

正規表現は文字列として "re.compile()" に渡されます。正規表現は文字列と
して扱われますが、それは正規表現が Python 言語のコアシステムに含まれな
いためです、そのため正規表現を表わす特殊な構文はありません。 (正規表現
を全く必要としないアプリケーションも存在します、そのためそれらを含めて
言語仕様を無駄に大きくする必要はありません) その代わり、 "re" モジュー
ルは "socket" や "zlib" モジュールのような通常の C 拡張モジュールとし
て Python に含まれています。

正規表現を文字列としておくことで Python 言語はより簡素に保たれています
が、そのため1つの欠点があります、これについては次の節で話題とします。


バックスラッシュ感染症
----------------------

先に述べたように、正規表現は特別な形式や特殊な文字の特別な意味を意味を
除くことを示すためにバックスラッシュ文字 ("'\'") を利用します。これは
Python が文字列リテラルに対して、同じ文字を同じ目的で使うことと衝突し
ます。

"\section" という文字列 (これは LaTeX ファイルでみかけます) にマッチす
る正規表現を書きたいとします。どんなプログラムを書くか考え、マッチして
欲しい文字列をはじめに考えます。次に、バックスラッシュや他の特殊文字を
バックスラッシュに続けて書くことでエスケープしなければいけません、その
結果 "\\section" のような文字列となります。こうしてできた
"re.compile()" に渡す文字列は "\\section" でなければいけません。しかし
、これを Python の文字列リテラルとして扱うにはこの二つのバックスラッシ
ュを *再び* エスケープする必要があります。

+---------------------+--------------------------------------------+
| 文字                | 段階                                       |
|=====================|============================================|
| "\section"          | マッチさせるテキスト                       |
+---------------------+--------------------------------------------+
| "\\section"         | "re.compile()" のためのバックスラッシュエ  |
|                     | スケープ                                   |
+---------------------+--------------------------------------------+
| ""\\\\section""     | 文字列リテラルのためのバックスラッシュエス |
|                     | ケープ                                     |
+---------------------+--------------------------------------------+

要点だけをいえば、リテラルとしてのバックスラッシュにマッチさせるために
、正規表現文字列として "'\\\\'" と書かなければいけません、なぜなら正規
表現は "\\" であり、通常の Python の文字列リテラルとしてはそれぞれのバ
ックスラッシュは "\\" で表現しなければいけないからです。正規表現に関し
てこのバックスラッシュの繰り返しの機能は、たくさんのバックスラッシュの
繰り返しを生むことになり、その結果として作られる文字列は理解することが
難しくなります。

この問題の解決策としては正規表現に対しては Python の raw string 記法を
使うことです; "'r'" を文字列リテラルの先頭に書くことでバックスラッシュ
は特別扱いされなくなります、つまり ""\n"" は改行を含む1つの文字からな
る文字列であるのに対して、 "r"\n"" は2つの文字 "'\'" と "'n'" を含む文
字列となります。多くの場合 Python コードの中の正規表現はこの raw
string 記法を使って書かれます。

それに加えて、正規表現では有効であるものの Python の文字列リテラルとし
ては有効でない特殊文字のエスケープシーケンスは、現在では
"DeprecationWarning" を引き起こし、最終的には "SyntaxError" となります
。すなわち、そのようなシーケンスは raw string 記法を使うか、バックスラ
ッシュによるエスケープを使わないかぎり無効になることを意味します。

+---------------------+--------------------+
| 通常の文字列        | Raw string         |
|=====================|====================|
| ""ab*""             | "r"ab*""           |
+---------------------+--------------------+
| ""\\\\section""     | "r"\\section""     |
+---------------------+--------------------+
| ""\\w+\\s+\\1""     | "r"\w+\s+\1""      |
+---------------------+--------------------+


マッチの実行
------------

一旦コンパイルした正規表現を表現するオブジェクトを作成したら、次に何を
しますか? パターンオブジェクトはいくつかのメソッドや属性を持っています
。ここでは、その中でも最も重要なものについて扱います; 完全なリストは
"re" ドキュメントを参照して下さい。

+--------------------+-------------------------------------------------+
| メソッド/属性      | 目的                                            |
|====================|=================================================|
| "match()"          | 文字列の先頭で正規表現とマッチするか判定します  |
|                    | 。                                              |
+--------------------+-------------------------------------------------+
| "search()"         | 文字列を先頭から走査して、正規表現がどこにマッ  |
|                    | チするか調べます。                              |
+--------------------+-------------------------------------------------+
| "findall()"        | 正規表現にマッチする部分文字列を全て探しだしリ  |
|                    | ストとして返します。                            |
+--------------------+-------------------------------------------------+
| "finditer()"       | 正規表現にマッチする部分文字列を全て探しだし    |
|                    | *iterator* として返します 。                    |
+--------------------+-------------------------------------------------+

"match()" と "search()" はマッチするものが見つからなければ "None" を返
します。 成功すればそれらは Match オブジェクト のインスタンスを返しま
す。このオブジェクトにはマッチした情報が含まれます: マッチの開始と終了
位置、マッチした部分文字列、など。

You can learn about this by interactively experimenting with the "re"
module.

この HOWTO では例として標準の Python インタプリタを使います。最初に
Python インタプリタを起動して、 "re" モジュールをインポートし、正規表
現をコンパイルします:

   >>> import re
   >>> p = re.compile('[a-z]+')
   >>> p
   re.compile('[a-z]+')

さて、いろいろな文字列を使って正規表現 "[a-z]+" に対するマッチングを試
してみましょう。空の文字列は全くマッチしません、なぜなら "+" は「1 回
以上の繰り返し」を意味するからです。この場合では "match()" は "None"
を返すべきで、インタプタは何も出力しません。明確にするために "match()"
の結果を明示的に出力することもできます:

   >>> p.match("")
   >>> print(p.match(""))
   None

では、今度はマッチするはずの文字列、例えば "tempo" を試してみましょう
。このケースでは、 "match()" は match object を返すので、後で使うため
に結果を変数に記憶しておくべきです。

   >>> m = p.match('tempo')
   >>> m
   <re.Match object; span=(0, 5), match='tempo'>

これでマッチした文字列についての情報を Match オブジェクト に問い合わせ
ることが出来ます。 Match オブジェクトインスタンスはいくつかのメソッド
と属性も持っていて、最も重要なのは次のものです:

+--------------------+----------------------------------------------+
| メソッド/属性      | 目的                                         |
|====================|==============================================|
| "group()"          | 正規表現にマッチした文字列を返す             |
+--------------------+----------------------------------------------+
| "start()"          | マッチの開始位置を返す                       |
+--------------------+----------------------------------------------+
| "end()"            | マッチの終了位置を返す                       |
+--------------------+----------------------------------------------+
| "span()"           | マッチの位置 (start, end) を含むタプルを返す |
+--------------------+----------------------------------------------+

これらのメソッドを試せば、その意味はすぐに理解できます:

   >>> m.group()
   'tempo'
   >>> m.start(), m.end()
   (0, 5)
   >>> m.span()
   (0, 5)

"group()" は正規表現でマッチした部分文字列を返します。 "start()" と
"end()" はそれぞれ、マッチの開始インデクスと終了インデクスを返します。
"span()" は開始と終了のインデクスを一つのタプルにして返します。
"match()" メソッドは正規表現が文字列の開始位置でマッチするかどうかだけ
をチェックするので、 "start()" は必ずゼロを返します。 しかし、
"search()" メソッドではパターンを文字列全体について走査するので、マッ
チの開始はゼロにならないかもしれません。

   >>> print(p.match('::: message'))
   None
   >>> m = p.search('::: message'); print(m)
   <re.Match object; span=(4, 11), match='message'>
   >>> m.group()
   'message'
   >>> m.span()
   (4, 11)

実際のプログラムでは Match オブジェクト を変数に記憶しておき, その次に
"None" なのか調べるのが一般的なスタイルです。普通このようにします:

   p = re.compile( ... )
   m = p.match( 'string goes here' )
   if m:
       print('Match found: ', m.group())
   else:
       print('No match')

あるパターンにマッチするもの全てを返す Pattern インスタンスのメソッド
が2つあります。 "findall()" はマッチした文字列のリストを返します:

   >>> p = re.compile(r'\d+')
   >>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
   ['12', '11', '10']

この例では、文字列リテラルを raw string リテラルにするプレフィックス
"r" が必要です。これは、正規表現とは異なり、通常の "調理済み" 文字列リ
テラルにおけるエスケープシーケンスは Python では認識されないためであり
、現在では "DeprecationWarning" を引き起こし、最終的には "SyntaxError"
となります。詳しくは バックスラッシュ感染症 を参照してください。

"findall()" は結果を返す前に完全なリストを必ず生成してしまいます。いっ
ぽう "finditer()" メソッドは マッチオブジェクト インスタンスのシーケン
スを *iterator* として返します:

   >>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
   >>> iterator  
   <callable_iterator object at 0x...>
   >>> for match in iterator:
   ...     print(match.span())
   ...
   (0, 2)
   (22, 24)
   (29, 31)


モジュールレベルの関数
----------------------

パターンオブジェクトを作ってそのメソッドを呼び出す、とする必要は必ずし
もありません。 "re" モジュールはトップレベルの関数として "match()",
"search()", "findall()", "sub()" などを用意しています。これら関数は、
対応するメソッドの最初の引数に RE が追加されただけで後は同じで、
"None" か Match オブジェクト インスタンスを返すのも同じです:

   >>> print(re.match(r'From\s+', 'Fromage amk'))
   None
   >>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998')  
   <re.Match object; span=(0, 5), match='From '>

内部的には、これら関数は単にあなたのためにパターンオブジェクトを生成し
、対応するメソッドを呼び出すだけのことです。とともに、将来の呼び出しで
同じ RE のパースが何度も何度も必要とならないよう、コンパイル済みオブジ
ェクトはキャッシュされます。

これらモジュールレベル関数を使うのと、パターンを自身で作って自身で呼び
出すのとでどちらを使うべきでしょう? 正規表現をループの内側で使うならば
、プリコンパイルは関数呼び出しを減らします。ループの外側であれば、内部
キャッシュのおかげで、どちらでも大差ありません。


コンパイルフラグ
----------------

コンパイルフラグは正規表現の動作をいくつかの側面から変更します。フラグ
は "re" モジュール下で二つの名前で利用することができます、例えば長い名
前は "IGNORECASE" で短い名前は1文字で "I" のようになっています。 (1文
字形式は Perl のパターン修飾子と同じ形式を使います; 例えば
"re.VERBOSE" の短かい形式は "re.X" です。) 複数のフラグが OR ビット演
算で指定することができます; 例えば "re.I | re.M" は "I" と "M" フラグ
の両方を設定します。

ここに利用可能なフラグの表があります、それぞれについてのより詳細な説明
が後に続きます。

+-----------------------------------+----------------------------------------------+
| Flag                              | 意味                                         |
|===================================|==============================================|
| "ASCII", "A"                      | "\w", "\b", "\s", そして "\d" などをそれぞれ |
|                                   | のプロパティをもつ ASCII 文字だけにマッチさ  |
|                                   | せます。                                     |
+-----------------------------------+----------------------------------------------+
| "DOTALL", "S"                     | "." を改行を含む任意の文字にマッチするように |
|                                   | します。                                     |
+-----------------------------------+----------------------------------------------+
| "IGNORECASE", "I"                 | 大文字小文字を区別しないマッチを行います。   |
+-----------------------------------+----------------------------------------------+
| "LOCALE", "L"                     | ロケールに対応したマッチを行います。         |
+-----------------------------------+----------------------------------------------+
| "MULTILINE", "M"                  | "^" や "$" の意味を変更し、複数行文字列に対  |
|                                   | するマッチングを行います。                   |
+-----------------------------------+----------------------------------------------+
| "VERBOSE", "X" ('X' は 'extended' | 冗長な正規表現を利用できるようにして、よりき |
| の 'X')                           | れいで理解しやすくまとめる ことができます。  |
+-----------------------------------+----------------------------------------------+

re.I
re.IGNORECASE

   大文字と小文字を区別しないマッチングを実行します; 文字クラスと文字
   列リテラルは大文字か小文字かに関係なくパターンにマッチします。例え
   ば、 "[A-Z]" は小文字のアルファベットにもマッチします。 "ASCII" フ
   ラグによって非 ASCII 文字のマッチングが無効化されていなければ、完全
   なユニコードのマッチングも可能です。ユニコードで "[a-z]" または
   "[A-Z]" が "IGNORECASE" フラグとともに使われると、 52個の ASCII 文
   字に加えて 次の4つの 非 ASCII 文字にマッチします: 'İ' (U+0130, ラテ
   ン語の大文字 I で、上部に点がついたもの), 'ı' (U+0131, ラテン語の小
   文字 i で上部に点がない), 'ſ' (U+017F, ラテン語の小文字 s),  'K'
   (U+212A, ケルビン記号)。 "Spam" は "'Spam'", "'spam'", "'spAM'", そ
   して "'ſpam'" にマッチします (ただし最後の文字列はユニコードモード
   の場合のみマッチします)。この「小文字化」は現在のロケールを考慮しま
   せん; ただし "LOCALE" フラグをセットした場合はロケールを考慮します
   。

re.L
re.LOCALE

   "\w", "\W", "\b",  "\B" と小文字大文字の区別を無視したマッチングを
   、 Unicode データベースではなく現在のロケールに従って行います。

   ロケールは言語の違いを考慮したプログラムを書くことを手助けすること
   を目的とした C ライブラリの機能です。例えば、エンコードされたフラン
   ス語のテキストを処理していて、"\w+" を使って単語のマッチを行いたい
   とします。ですがこの場合、 "\w" はバイトパターンにおいて文字クラス
   "[A-Za-z]" だけにマッチします; すなわち "é" や "ç" に対応するバイト
   列にはマッチしません。もしシステムが適切に設定されていて、ロケール
   がフランス語に設定されていれば、ある C 関数はプログラムに "é" に対
   応するバイト列も文字として考慮するべきであると伝えます。正規表現を
   コンパイルするときに "LOCALE" フラグを設定すると、コンパイルされた
   オブジェクトが "\w" に対してロケールを考慮する C 関数を使うようにな
   ります; これにより処理は遅くなりますが、 "\w+" を期待通りフランス語
   の単語にマッチさせることが可能になります。このフラグを Python 3 で
   利用することは推奨されません。なぜならロケールの仕組みは非常に信頼
   性が低く、同時にひとつの "文化" しか扱うことができず、また8ビットの
   ロケールでしか正しく動作しないからです。Python 3 ではユニコード (文
   字列の) パターンに対してユニコードのマッチングがデフォルトで有効化
   されており、これにより異なるロケールまたは言語を同時に扱うことがで
   きます。

re.M
re.MULTILINE

   ("^" と "$" についてはまだ説明していません; これらは さらなる特殊文
   字 の節で説明します。)

   通常 "^" は文字列の先頭にマッチし、 "$" は文字列の末尾と文字列の末
   尾に改行(があれば)その直前にマッチします。このフラグが指定されると
   、 "^" は文字列の先頭と文字列の中の改行に続く各行の先頭にマッチしま
   す。同様に "$" 特殊文字は文字列の末尾と各行の末尾(各改行の直前)のど
   ちらにもマッチします。

re.S
re.DOTALL

   特別な文字 "'.'" を改行を含む全ての任意の文字とマッチするようにしま
   す; このフラグが無しでは、 "'.'" は改行 *以外* の全てにマッチします
   。

re.A
re.ASCII

   "\w", "\W", "\b", "\B", "\s", "\S" が、完全な Unicode マッチングで
   はなく、ASCII のみのマッチングをするようにします。これは Unicode パ
   ターンにのみ意味があり、byte パターンには無視されます。

re.X
re.VERBOSE

   このフラグはより柔軟な形式で正規表現を読み易く書けるようにします。
   このフラグを指定すると、正規表現の中の空白は無視されます、ただし、
   文字クラス内やエスケープされていないバックスラッシュに続く空白の場
   合は例外として無視されません; これによって正規表現をまとめたり、イ
   ンデントしてより明確にすることができます。このフラグはさらにエンジ
   ンが無視するコメントを追加することもできます; コメントは "'#'" で示
   します、これは文字クラスやエスケープされていないバックスラッシュに
   続くものであってはいけません。

   例えば、ここに "re.VERBOSE" を利用した正規表現があります; 読み易い
   と思いませんか?

      charref = re.compile(r"""
       &[#]                # Start of a numeric entity reference
       (
           0[0-7]+         # Octal form
         | [0-9]+          # Decimal form
         | x[0-9a-fA-F]+   # Hexadecimal form
       )
       ;                   # Trailing semicolon
      """, re.VERBOSE)

   冗長な表現を利用しない設定の場合、正規表現はこうなります:

      charref = re.compile("&#(0[0-7]+"
                           "|[0-9]+"
                           "|x[0-9a-fA-F]+);")

   上の例では、Python の文字列リテラルの自動結合によって正規表現を小さ
   な部分に分割しています、それでも "re.VERBOSE" を使った場合に比べる
   とまだ難しくなっています。


パターンの能力をさらに
======================

ここまでで、正規表現の機能のほんの一部を扱ってきました。この節では、新
たにいくつかの特殊文字とグループを使ってマッチしたテキストの一部をどう
取得するかについて扱います。


さらなる特殊文字
----------------

これまでで、まだ扱っていない特殊文字がいくつかありました。そのほとんど
をこの節で扱っていきます。

残りの特殊文字の内いくつかは *ゼロ幅アサーション zero-width-
assertions* に関するものです。これらは文字列に対してエンジンを進めませ
ん; 文字列を全く利用しない代わりに、単純に成功か失敗かを利用します。例
えば、 "\b" は現在位置が単語の境界であることを示します; "\b" によって
エンジンの読んでいる位置は全く変化しません。つまり、これはゼロ幅アサー
ションは繰り返し使うことがありません、一度ある位置でマッチしたら、明ら
かに無限回マッチできます。

"|"
   代替 (alternation) または "or" 演算子です。 *A* と *B* が正規表現の
   場合、 "A|B" は *A* と *B* のどちらかにマッチするような文字列にマッ
   チします。複数の文字からなる文字列による代替処理が適切に動作するた
   めに、 "|" の優先度は非常に低く設定されています。 "Crow|Servo" は
   "'Crow'" か "'Servo'" のどちらかにマッチするパターンであり、 「
   "'Cro'" に続いて "'w'" または "'S'" があり、さらに "'ervo'" が続く
   」という意味ではありません。

   リテラル "'|'" にマッチするには、 "\|" を利用するか、 "[|]" のよう
   に文字クラス内に収めて下さい。

"^"
   行の先頭にマッチします。 "MULTILINE" フラグが設定されない場合には、
   文字列の先頭にのみマッチします。 "MULTILINE" モードでは文字列内の各
   改行の直後にマッチします。

   例えば、行の先頭の "From" にのみマッチさせたい場合には "^From" 正規
   表現を利用します。

      >>> print(re.search('^From', 'From Here to Eternity'))  
      <re.Match object; span=(0, 4), match='From'>
      >>> print(re.search('^From', 'Reciting From Memory'))
      None

   リテラル "'^'" にマッチするには "\^" を利用してください。

"$"
   行の末尾にマッチします、行の末尾は文字列の末尾と改行文字の直前とし
   て定義されます。

      >>> print(re.search('}$', '{block}'))  
      <re.Match object; span=(6, 7), match='}'>
      >>> print(re.search('}$', '{block} '))
      None
      >>> print(re.search('}$', '{block}\n'))  
      <re.Match object; span=(6, 7), match='}'>

   リテラル "'$'" にマッチするには、 "\$" を利用するか、 "[$]" のよう
   に文字クラス内に収めて下さい。

"\A"
   文字列の先頭にのみマッチします。 "MULTILINE" モードでない場合には
   "\A" と "^" は実質的に同じです。 "MULTILINE" モードでのこれらの違い
   は: "\A" は依然として文字列の先頭にのみマッチしますが、 "^" は文字
   列内に改行文字に続く部分があればそこにマッチすることです。

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

"\b"
   単語の境界。これはゼロ幅アサーションで、単語の始まりか終わりにのみ
   マッチします。単語は英数文字のシーケンスとして定義されます、つまり
   単語の終わりは空白か非英数文字として表われます。

   以下の例では "class" がそのものの単語のときのみマッチします; 別の単
   語内に含まれている場合はマッチしません。

      >>> p = re.compile(r'\bclass\b')
      >>> print(p.search('no class at all'))
      <re.Match object; span=(3, 8), match='class'>
      >>> print(p.search('the declassified algorithm'))
      None
      >>> print(p.search('one subclass is'))
      None

   この特殊シーケンスを利用するときには二つの微妙な点を心にとめておく
   必要があります。まずひとつめは Python の文字列リテラルと表現の間の
   最悪の衝突を引き起すことです。Python の文字列リテラルでは "\b" は
   ASCII 値8のバックスペース文字です。raw string を利用していない場合
   、Python は "\b" をバックスペースに変換し、正規表現は期待するものと
   マッチしなくなります。以下の例はさきほどと同じ正規表現のように見え
   ますが、正規表現文字列の前の "'r'" が省略されています。

      >>> p = re.compile('\bclass\b')
      >>> print(p.search('no class at all'))
      None
      >>> print(p.search('\b' + 'class' + '\b'))
      <re.Match object; span=(0, 7), match='\x08class\x08'>

   ふたつめはこのアサーションが利用できない文字列クラスの内部では
   Python の文字列リテラルとの互換性のために、 "\b" はバックスペース文
   字を表わすことになるということです。

"\B"
   別のゼロ幅アサーションで、 "\b" と逆で、現在の位置が単語の境界でな
   いときにのみマッチします。


グルーピング
------------

正規表現にマッチするかどうかだけでなく、より多くの情報を得なければいけ
ない場合は多々あります。正規表現はしばしば、正規表現をいくつかのサブグ
ループに分けて興味ある部分にマッチするようにして、文字列を分割するのに
使われます。例えば、RFC-822 ヘッダ行は "':'" を挟んでこのようにヘッダ
名と値に分割されます:

   From: author@example.com
   User-Agent: Thunderbird 1.5.0.9 (X11/20061227)
   MIME-Version: 1.0
   To: editor@example.com

これはヘッダ全体にマッチし、そしてヘッダ名にマッチするグループとヘッダ
の値にマッチする別のグループを持つように正規表現を書くことで扱うことが
できます。

グループはメタ文字 "'('" と "')'" であらわされます。 "'('" と "')'" は
数式における意味とほぼ同じ意味を持っています; その中に含まれる表現をひ
とまとまりにし、それらに対して "*", "+", "?", または "{m,n}" のような
数量子を使った繰り返しを表現することもできます。例えば、 "(ab)*" は
"ab" の0回以上の繰り返しにマッチします。

   >>> p = re.compile('(ab)*')
   >>> print(p.match('ababababab').span())
   (0, 10)

"'('", "')'" で指示されたグループは、マッチしたテキスト開始と終了位置
もキャプチャします; "group()", "start()", "end()", "span()" に引数を与
えて取り出せます。グループはゼロ始まりの数値です。グループ 0 は常に使
えます; それは RE でマッチした全体で、 Match オブジェクト メソッドの全
てはグループ 0 をデフォルト引数にしています。マッチするテキストの範囲
をキャプチャしないグループの書き方はのちほど見ることにします。

   >>> p = re.compile('(a)b')
   >>> m = p.match('ab')
   >>> m.group()
   'ab'
   >>> m.group(0)
   'ab'

サブグループは左から右へ1づつ番号付けされます。グループはネストしても
かまいません; 番号を決めるには、単に開き括弧を左から右へ数え上げます。

   >>> p = re.compile('(a(b)c)d')
   >>> m = p.match('abcd')
   >>> m.group(0)
   'abcd'
   >>> m.group(1)
   'abc'
   >>> m.group(2)
   'b'

"group()" には一回に複数の引数を渡してもかまいません、その場合にはそれ
らのグループに対応する値を含むタプルを返します。

   >>> m.group(2,1,2)
   ('b', 'abc', 'b')

"groups()" メソッドは 1 から全てのサブグループの文字列を含むタプルを返
します。:

   >>> m.groups()
   ('abc', 'b')

パターン中で後方参照を利用することで、前に取り出されたグループが文字列
の中の現在位置で見つかるように指定できます。例えば、"\1" はグループ1の
内容が現在位置で見つかった場合成功し、それ以外の場合に失敗します。
Python の文字列リテラルでもバックスラッシュに続く数字は任意の文字を文
字列に含めるために使われるということを心に留めておいて下さい、そのため
正規表現で後方参照を含む場合には raw string を必ず利用して下さい。

例えば、以下の正規表現は二重になった単語を検出します。

   >>> p = re.compile(r'\b(\w+)\s+\1\b')
   >>> p.search('Paris in the the spring').group()
   'the the'

このような後方参照は文字列を検索するだけの用途では多くの場合役に立ちま
せん。--- このように繰り返されるテキストフォーマットは少数です。--- し
かし、文字列の置換をする場合には *とても* 有効であることに気づくでしょ
う。


取り出さないグループと名前つきグループ
--------------------------------------

念入りに作られた正規表現は多くのグループを利用します、その利用法には対
象となる部分文字列を取り出す、正規表現自身をグループ化したり構造化する
、という二つの方法があります。複雑な正規表現では、グループ番号を追って
いくことは困難になっていきます。この問題の解決を助ける二つの機能があり
ます。その両方が正規表現を拡張するための一般的な構文を利用します、まず
はそれらをみてみましょう。

Perl 5 は標準正規表現にパワフルな拡張を加えたことでよく知られています
。それらの新しい機能のために Perl 開発者たちは、Perl正規表現と標準正規
表現との混乱を招く違いなしには、新たな一文字メタキャラクタも "\" では
じまる新たな特殊シーケンスもどちらも選択出来ませんでした。たとえば彼ら
がもし "&" を新たなメタキャラクタとして選んでいたら、 "&" が通常文字と
みなされていた古い正規表現は "\&" や "[&]" のように書くことでエスケー
プされなければならなかったでしょう。

解決策として Perl 開発者が選んだものは "(?...)" を正規表現構文として利
用することでした。括弧の直後の "?" は構文エラーとなります、これは "?"
で繰り返す対象がないためです、そのためこれは互換性の問題を持ち込みませ
ん。 "?" の直後の文字はどの拡張が利用されるかを示しています、つまり、
"(?=foo)" は一つの拡張を利用したもの (肯定先読みアサーション) となり、
"(?:foo)" は別の拡張を利用した表現("foo" を含む取り込まないグループ)と
なります。

Python は Perl の拡張のいくつかをサポートし、また、Perl の拡張に一つ拡
張を加えています。クエスチョンマークに続く最初の文字が "P" のものは、
そうです、Python 固有の拡張です。

一般化された拡張構文についてはわかりましたので、いよいよ複雑な正規表現
内でのグループの扱いを単純化する機能に話を戻しましょう。

ときとしてあなたは、正規表現の一部として使いたいけれども、その内容を取
り出すことに興味がないようなグループを記述する必要に迫られます。このた
めには、取り出さないグループ: "(?:...)" を使います。 "..." 部分は任意
の正規表現です。

   >>> m = re.match("([abc])+", "abc")
   >>> m.groups()
   ('c',)
   >>> m = re.match("(?:[abc])+", "abc")
   >>> m.groups()
   ()

マッチしたグループの内容を取得しないということを除けば、取り込まないグ
ループは厳密に取り込むグループと同様に振る舞います; この中に何を入れて
もかまいません、 "*" のような繰り返しの特殊文字で繰り返したり、他のグ
ループ (取り込むまたは取り込まない) の入れ子にすることもでいます。
"(?:...)" は特に、既にあるパターンを変更する際に便利です、なぜなら他の
番号づけ新しいグループを変更することなく新しいグループを追加することが
できます。取り込むグループと取り込まないグループで検索のパフォーマンス
に差がないことにも触れておくべきことです; どちらも同じ速度で動作します
。

より重要な機能は名前つきグループです: 番号で参照する代わりに、グループ
に対して名前で参照できます。

名前つきグループのための構文は、 Python 固有拡張の一つ:
"(?P<name>...)" を使います。 *name* は、もちろん、グループの名前です。
名前つきグループは取り込むグループと完全に同じに振る舞い、加えて名前が
関連付けられます。 Match オブジェクト の取りこむグループを扱うメソッド
は全て、番号によるグループ参照のための整数、名前によるグループ参照のた
めの文字列、ともに許容しています。名前つきグループにも番号が振られます
ので、グループについての情報を、2つの方法で取り出せます:

   >>> p = re.compile(r'(?P<word>\b\w+\b)')
   >>> m = p.search( '(((( Lots of punctuation )))' )
   >>> m.group('word')
   'Lots'
   >>> m.group(1)
   'Lots'

さらに、名前付きのグループを "groupdict()" を使って辞書として取り出す
こともできます:

   >>> m = re.match(r'(?P<first>\w+) (?P<last>\w+)', 'Jane Doe')
   >>> m.groupdict()
   {'first': 'Jane', 'last': 'Doe'}

名前つきグループは、番号を覚える代わりに簡単に覚えられる名前で管理でき
るため、便利です。以下は "imaplib" モジュールで使われている正規表現の
例です:

   InternalDate = re.compile(r'INTERNALDATE "'
           r'(?P<day>[ 123][0-9])-(?P<mon>[A-Z][a-z][a-z])-'
           r'(?P<year>[0-9][0-9][0-9][0-9])'
           r' (?P<hour>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])'
           r' (?P<zonen>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])'
           r'"')

取得する番号9を覚えるよりも、 "m.group('zonem')" で取得した方が明らか
に簡単にすみます。

後方参照のための構文 "(...)\1" はグループ番号への参照となっています。
グループ番号の代わりに、グループ名を利用する変種があるのは当然でしょう
。 これはもう一つの Python 拡張です: "(?P=name)" は、 *name* という名
前のグループの内容が、現在の位置で再びマッチすることを示しています。
同じ単語が2つ連なっているのを見つける正規表現 "\b(\w+)\s+\1\b" は
"\b(?P<word>\w+)\s+(?P=word)\b" のように書けます:

   >>> p = re.compile(r'\b(?P<word>\w+)\s+(?P=word)\b')
   >>> p.search('Paris in the the spring').group()
   'the the'


先読みアサーション (Lookahead Assertions)
-----------------------------------------

他のゼロ幅アサーションは先読みアサーションです。先読みアサーションは肯
定、否定の両方の形式が利用可能です、これを見てください:

"(?=...)"
   肯定先読みアサーション。 "..." で表わす正規表現が現在位置でマッチす
   れば成功し、それ以外の場合失敗します。しかし、表現が試行された場合
   でもエンジンは先に進みません; パターンの残りの部分はアサーションの
   開始時点から右に試行します。

"(?!...)"
   否定先読みアサーション。これは肯定アサーションの逆で、正規表現が文
   字列の現在位置にマッチ *しなかった* 場合に成功します。

より具体的にするため、先読みが便利な場合をみてみましょう。ファイル名に
マッチし、 "." で分けられた基本部分と拡張子に分離する単純なパターンを
考えましょう。例えば、 "news.rc" は "news" が基本部分で "rc" がファイ
ル名の拡張子です。

マッチするパターンはとても単純です:

".*[.].*$"

"." はメタキャラクタですので特別に扱わなければなりませんから、文字クラ
ス内に入れて、そのものとだけマッチするようにしていることに注目です。末
尾の "$" にも注目してください; これは残り全ての文字列が拡張子に含まれ
るべきであることを保障するために追加しています。この正規表現は
"foo.bar", "autoexec.bat", "sendmail.cf", "printers.conf" にマッチしま
す。

さて、問題を少し複雑にしてみましょう; 拡張子が "bat" でないファイル名
にマッチしたい場合はどうでしょう？間違った試み:

".*[.][^b].*$" この最初の "bat" を除く試みは、最初の文字が "b" でない
ことを要求します。これは誤っています、なぜなら "foo.bar" にもマッチし
ないからです。

".*[.]([^b]..|.[^a].|..[^t])$"

正規表現が混乱してきました。最初の解決策を取り繕って、以下の場合に合わ
せることを要求しています: 拡張子の最初の文字は "b" でなく; 二番目の文
字は "a" でなく; 三番目の文字は "t" でない。これは "foo.bar" を受け付
けますが、 "autoexec.bat" は拒否します。しかし、三文字の拡張子を要求し
、 "sendmail.cf" のような二文字の拡張子を受け付けません。これを修正す
るのにパターンを再び複雑にすることになります。

".*[.]([^b].?.?|.[^a]?.?|..?[^t]?)$"

三番目の試みでは、 "sendmail.cf" のように三文字より短い拡張子とマッチ
するために第二第三の文字を全てオプションにしています。

パターンはさらに複雑さを増し、読みにくく、理解が難しくなりました。より
悪いことに、問題が "bat" と "exe" 両方を拡張子から除きたい場合に変わっ
た場合、パターンはより複雑で混乱しやすいものになります。

否定先読みはこの混乱全てを取り除きます:

".*[.](?!bat$)[^.]*$" 否定先読みは以下を意味します: この位置で拡張子
"bat" にマッチしない場合、残りのパターンが試行されます; もし "bat$" に
マッチすればパターン全体が失敗します。"$" を続けることで、
"sample.batch" にように "bat" で始まる拡張子を許容することを保証してい
ます。 このパターンで "[^.]*" を使うことで、ファイル名に複数のドットが
あったときにも上手くいくようになります。

他のファイル名の拡張子を除くことも簡単です; 単純にアサーション内に拡張
子を代替 (or) で加えます。以下のパターンは "bat" や "exe" のどちらかで
終わるファイル名を除外します:

".*[.](?!bat$|exe$)[^.]*$"


文字列を変更する
================

ここまででは単純に静的な文字列に対する検索を実行してきました。正規表現
は文字列を様々な方法で変更するのにもよく使われます。変更には以下のパタ
ーンメソッドが利用されます:

+--------------------+-------------------------------------------------+
| メソッド/属性      | 目的                                            |
|====================|=================================================|
| "split()"          | 文字列をリストに分割する、正規表現がマッチした  |
|                    | 全ての場所で分割を行う                          |
+--------------------+-------------------------------------------------+
| "sub()"            | 正規表現にマッチした全ての文字列を発見し、別の  |
|                    | 文字列に置き換えます                            |
+--------------------+-------------------------------------------------+
| "subn()"           | "sub()" と同じことをしますが、新しい文字列と置  |
|                    | き換えの回数を返します                          |
+--------------------+-------------------------------------------------+


文字列の分割
------------

"split()" メソッドは文字列を正規表現にマッチした場所で分割し、リストで
返却します。文字列の "split()" メソッドに似てはいますが、もっとずっと
一般化したデリミタで分割出来ます; 文字列の "split()" メソッドは単に空
白文字か固定文字列で分割出来るだけです。ご想像通り、モジュールレベルの
"re.split()" 関数もあります。

.split(string[, maxsplit=0])

   *string* を正規表現のマッチで分割します。正規表現内に取り込むための
   括弧が利用されている場合、その内容も結果のリストの一部として返され
   ます。 *maxsplit* が非ゼロの場合、最大で *maxsplit* の分割が実行さ
   れます。

*maxsplit* に値を渡すことで、分割される回数を制限することができます。
*maxsplit* が非ゼロの場合、最大で *maxsplit* の分割が行なわれ、文字列
の残りがリストの最終要素として返されます。以下の例では、デリミタは任意
の英数文字のシーケンスです。

   >>> p = re.compile(r'\W+')
   >>> p.split('This is a test, short and sweet, of split().')
   ['This', 'is', 'a', 'test', 'short', 'and', 'sweet', 'of', 'split', '']
   >>> p.split('This is a test, short and sweet, of split().', 3)
   ['This', 'is', 'a', 'test, short and sweet, of split().']

興味の対象がデリミタの間のテキストだけでなく、デリミタが何なのかという
ことを知りたい場合はよくあります。取りこみ用の括弧を正規表現に使った場
合、その値もリストの一部として返されます。以下の呼び出しを比較してみま
しょう:

   >>> p = re.compile(r'\W+')
   >>> p2 = re.compile(r'(\W+)')
   >>> p.split('This... is a test.')
   ['This', 'is', 'a', 'test', '']
   >>> p2.split('This... is a test.')
   ['This', '... ', 'is', ' ', 'a', ' ', 'test', '.', '']

モジュールレベル関数 "re.split()" は最初の引数に利用する正規表現を追加
しますが、それ以外は同じです。

   >>> re.split(r'[\W]+', 'Words, words, words.')
   ['Words', 'words', 'words', '']
   >>> re.split(r'([\W]+)', 'Words, words, words.')
   ['Words', ', ', 'words', ', ', 'words', '.', '']
   >>> re.split(r'[\W]+', 'Words, words, words.', 1)
   ['Words', 'words, words.']


検索と置換
----------

もう一つのよくある作業は、パターンにマッチする全ての文字列を探し、異な
る文字列に置換します。 "sub()" メソッドは置換する値をとります、文字列
と関数の両方をとることができ、文字列を処理します。

.sub(replacement, string[, count=0])

   *string* 内で最も長く、他の部分と重複するところがない正規表現を
   *replacement* に置換した文字列を返します。パターンが見つからなかっ
   た場合 *string* は変更されずに返されます。

   オプション引数 *count* はパターンの出現の最大置換回数です; *count*
   は非負の整数でなければいけません。デフォルト値 0 は全ての出現で置換
   することを意味します。

ここに "sub()" メソッドを使った単純な例があります。これは色の名前を
"colour" に置換します:

   >>> p = re.compile('(blue|white|red)')
   >>> p.sub('colour', 'blue socks and red shoes')
   'colour socks and colour shoes'
   >>> p.sub('colour', 'blue socks and red shoes', count=1)
   'colour socks and red shoes'

"subn()" メソッドも同じ働きをしますが、新しい文字列と置換の実行回数を
含む 2-タプルを返します:

   >>> p = re.compile('(blue|white|red)')
   >>> p.subn('colour', 'blue socks and red shoes')
   ('colour socks and colour shoes', 2)
   >>> p.subn('colour', 'no colours at all')
   ('no colours at all', 0)

空文字列とのマッチは、直前の空文字列とマッチした部分と隣接していない場
合にのみ置換されます。

   >>> p = re.compile('x*')
   >>> p.sub('-', 'abxd')
   '-a-b--d-'

*replacement* が文字列の場合、文字列内のバックスラッシュエスケープは処
理されます。つまり、"\n" は改行文字に "\r" はキャリッジリターンに、等
となります。"\&" のような未知のエスケープシーケンスはそのまま残されま
す。"\6" のような後方参照は正規表現内の対応するグループにマッチする文
字列に置換されます。これを使うことで元のテキストの一部を、置換後の文字
列に組み込むことができます。

この例は単語 "section" に続く "{" と "}" で閉じられた文字列にマッチし
、 "section" を "subsection" に変更します:

   >>> p = re.compile('section{ ( [^}]* ) }', re.VERBOSE)
   >>> p.sub(r'subsection{\1}','section{First} section{second}')
   'subsection{First} subsection{second}'

"(?P<name>...)" 構文で定義された名前つきグループを参照するための構文も
あります。 "\g<name>" は "name" で名前づけされたグループにマッチする文
字列を利用し、 "\g<number>" は対応するグループ番号を利用します。つまり
"\g<2>" は "\2" と等価ですが、 "\g<2>0" のような置換文字列に対しては明
確に異なります。 ("\20" はグループ番号20への参照と解釈され、グループ2
の後にリテラル文字 "'0'" が続くとは解釈されません。) 以下に示す置換は
全て等価ですが、これらは文字列置換に全部で3種の変種を利用しています。

   >>> p = re.compile('section{ (?P<name> [^}]* ) }', re.VERBOSE)
   >>> p.sub(r'subsection{\1}','section{First}')
   'subsection{First}'
   >>> p.sub(r'subsection{\g<1>}','section{First}')
   'subsection{First}'
   >>> p.sub(r'subsection{\g<name>}','section{First}')
   'subsection{First}'

より細かな制御を手中にするために *replacement* として関数を使うことが
出来ます。 *replacement* が関数であれば、その関数は重なり合わない
*pattern* の発生のたびに呼び出されます。それぞれの呼び出しで、マッチし
た Match オブジェクト が引数として渡されるので、望みの置換と返却のため
にこの情報を利用出来ます。

続く例では、置換関数は十進数文字列を十六進数文字列に変換しています:

   >>> def hexrepl(match):
   ...     "Return the hex string for a decimal number"
   ...     value = int(match.group())
   ...     return hex(value)
   ...
   >>> p = re.compile(r'\d+')
   >>> p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.')
   'Call 0xffd2 for printing, 0xc000 for user code.'

モジュールレベルの "re.sub()" 関数を使うときには、パターンが最初の引数
として渡されます。パターンはオブジェクトや文字列をとります; 正規表現フ
ラグを指定する必要がある場合、パターンオブジェクトを最初の引数として使
うか、修飾子を埋め込んだパターン文字列を使うかしなければいけません、例
えば "sub("(?i)b+", "x", "bbbb BBBB")" は "'x x'" を返します。


よくある問題
============

正規表現はいくつかの応用に対して強力なツールですが、いくつかの部分でそ
れらの振る舞いは直感的ではなく、期待通りに振る舞わないことがあります。
この節では最もよくある落とし穴を指摘します。


文字列メソッドを利用する
------------------------

いくつかの場合 "re" モジュールを利用することは間違いである場合がありま
す。固定文字列や単一の文字クラスにマッチさせる場合や、 "IGNORECASE" フ
ラグのような "re" の機能を利用しない場合、正規表現の全ての能力は必要と
されていなでしょう。文字列は固定文字列に対する操作を実行するメソッドを
持っていて、大きな汎用化された正規表現エンジンではなく、目的のために最
適化された単一の小さな C loop で実装されているため、大抵の場合高速です
.

一つの例としては、単一の固定文字列を別の固定文字列に置き換える作業があ
るでしょう; 例えば "word" を "deed" で置換したい場合です。 "re.sub()"
はこの目的で使う関数のように思えますが、 "replace()" メソッドを利用す
ることを考えた方がいいでしょう。 "replace()" は単語内の "word" も置換
し、 "swordfish" を "sdeedfish" に変えますが、安直な正規表現 "word" も
同様に動作することに注意して下さい。(単語の一部に対する置換の実行を避
けるには、パターンを "\bword\b" として、 "word" の両側に単語の境界が要
求されるようにします。これは "replace()" の能力を越えた作業です。)

別のよくある作業は、文字列の中に出現する文字を全て削除することと、別の
文字で置換することです。この作業を "re.sub('\n', ' ', S)" のようにして
行うかもしれませんが、 "translate()" は削除と置換の両方の作業をこなし
、正規表現操作よりも高速に行うことができます。

要は、 "re" モジュールに向う前に問題が高速で単純な文字列メソッドで解決
できるか考えましょうということです。


match() 対 search()
-------------------

"match()" 関数は文字列の先頭に正規表現がマッチするかどうか調べるだけで
すが、その一方 "search()" はマッチするために文字列の先の方まで走査しま
す。 この違いを覚えておくことは重要なことです。 "match()" は開始位置0
でマッチが成功したときのみ報告する; もし開始位置0でマッチしなければ、
"match()" はそれを報告 *しない* 、ということを覚えておいてください。

   >>> print(re.match('super', 'superstition').span())
   (0, 5)
   >>> print(re.match('super', 'insuperable'))
   None

一方 "search()" は文字列の先の方まで走査し、最初にみつけたマッチを報告
します。:

   >>> print(re.search('super', 'superstition').span())
   (0, 5)
   >>> print(re.search('super', 'insuperable').span())
   (2, 7)

しばしば、 "re.match()" を使い、 ".*" を正規表現の最初に付け加える誘惑
にからされることがあるでしょう。この誘惑に打ち克って、代わりに
"re.search()" を利用すべきです。正規表現コンパイラはマッチを探す処理の
高速化のためにいくつかの解析を行います。そのような解析のうちのひとつは
マッチの最初の文字が何であるか評価することです; 例えば、 "Crow" で始ま
るパターンは "'C'" から始まらなければいけません。解析によってエンジン
は速やかに開始文字を探して走査します、 "'C'" が発見された場合にはじめ
て完全なマッチを試みます。

".*" を追加することはこの最適化を無効にします、文字列の終端までの走査
が必要となり、走査後には残りの正規表現とのマッチ部分を見つけるために引
き返すことになります。代わりに "re.search()" を利用して下さい。


貪欲 (greedy) 対非貪欲 (non-greedy)
-----------------------------------

正規表現を繰り返す場合、たとえば "a*" のように、できるだけパターンの多
くにマッチするように動作することになります。この動作は、例えば角括弧で
囲まれた HTML タグのような左右対称のデリミタの対にマッチしようという場
合に問題となります。単一の HTML タグにマッチする素朴な正規表現はうまく
動作しません、なぜならば ".*" は貪欲に動作するからです。

   >>> s = '<html><head><title>Title</title>'
   >>> len(s)
   32
   >>> print(re.match('<.*>', s).span())
   (0, 32)
   >>> print(re.match('<.*>', s).group())
   <html><head><title>Title</title>

正規表現は "'<html>'" 内の "'<'" にマッチし、 ".*" は残りの文字列の全
てにマッチします。 しかし、正規表現には依然として残っている部分があっ
て、 ">" は文字列の終端にマッチしないので、正規表現エンジンは一文字ず
つ ">" とマッチするまで引き返すことになります。 最終的にマッチする領域
は "'<html>'" の "'<'" から "'</title>'" の "'>'" まで広がりますが、こ
れは望んだ結果ではありません。

この場合の解決策は、非貪欲 (non-greedy) な数量子 "*?", "+?", "??", あ
るいは "{m,n}?" を使うことです。これらはできるだけ *少ない* テキストに
マッチしようとします。上記の例では、 "'>'" は "'<'" がマッチした直後の
文字からマッチするかどうかを調べられ、失敗すると同時にエンジンは文字を
先に進めながら、各ステップで "'>'" のマッチを試みます。この動作は正し
い結果を生成します:

   >>> print(re.match('<.*?>', s).group())
   <html>

(HTML や XML を正規表現でパースすることは苦痛を伴うものであることは記
憶に留めておいて下さい。素早く、汚いパターンは大抵の場合うまく動作しま
すが、HTML と XML は正規表現が破綻する特別な例です; 全ての可能な場合に
うまく動作する正規表現を書き上げたときには、パターンは *非常に* 複雑な
ものになります。そのような作業をする場合には HTML や XML パーサを利用
しましょう。)


re.VERBOSE の利用
-----------------

ここまでで、正規表現がとても簡潔な表記であることに気づいたでしょう、ま
た、正規表現は読みやすいものでもないということにも気づいたことでしょう
。そこそこに入り組んだ正規表現ははバックスラッシュ、括弧、特殊文字が長
く続いて、読みにくく、理解しづらいものになります。

そのような正規表現に対しては、正規表現をコンパイルする時に
"re.VERBOSE" フラグを指定することが助けになります。なぜなら、より明確
な書式で正規表現を書けるからです。

"re.VERBOSE" の効果はいくつかあります。正規表現内の文字クラス内に *無
い* 空白は無視されます。これは、 "dog | cat" のような表現が少々可読性
の落ちる "dog|cat" と等価となるということです、しかし、 "[a b]" は依然
として "'a'", "'b'", または空白にマッチします。加えて、正規表現にコメ
ントを入れることもできるようになります; "#" 文字から次の改行までがコメ
ントの範囲です。三重クォートを利用することで、正規表現をきちんとフォー
マットすることができます:

   pat = re.compile(r"""
    \s*                 # Skip leading whitespace
    (?P<header>[^:]+)   # Header name
    \s* :               # Whitespace, and a colon
    (?P<value>.*?)      # The header's value -- *? used to
                        # lose the following trailing whitespace
    \s*$                # Trailing whitespace to end-of-line
   """, re.VERBOSE)

これは下よりはるかに読みやすいです:

   pat = re.compile(r"\s*(?P<header>[^:]+)\s*:(?P<value>.*?)\s*$")


フィードバック
==============

正規表現は複雑な話題です。このドキュメントは助けになったでしょうか？わ
かりにくかったところや、あなたが遭遇した問題が扱われていない等なかった
でしょうか？もしそんな問題があれば、著者に改善の提案を送って下さい。

O'Reilly から出版されている Jeffrey Friedl の Mastering Regular
Expressions は正規表現に関するほぼ完璧な書籍です (訳注　日本語訳「詳説
正規表現」が出版されています) 。不幸なことに、この本は Perl と Java の
正規表現を集中して扱っていて、 Python の正規表現については全く扱ってい
ません、そのため Python プログラミングのためのレファレンスとして使うこ
とはできません。 (第一版はいまや削除された Python の "regex" モジュー
ルについて扱っていましたが、これはあまり役に立たないでしょう。) 図書館
で調べるのを検討してみましょう。
