Python 正規表現

正規表現は特殊な文字列パターンであり、ある文字列が特定のパターンにマッチするかを簡単にチェックするのに役立ちます。

Python はバージョン1.5から re モジュールを追加しました。これは Perl スタイルの正規表現パターンを提供します。

re モジュールにより、Python 言語は正規表現のすべての機能を備えています。

compile 関数は、パターン文字列とオプションのフラグ引数に基づいて正規表現オブジェクトを生成します。このオブジェクトは、正規表現のマッチングと置換に使用する一連のメソッドを備えています。

re モジュールは、これらのメソッドと完全に同じ機能を持つ関数も提供しており、これらの関数は最初の引数としてパターン文字列を使用します。

この章では、Python でよく使われる正規表現処理関数を主に紹介します。


re.match 関数

re.match は文字列の先頭からパターンのマッチングを試みます。先頭位置でマッチングが成功しない場合、match() は None を返します。

関数構文:

re.match(pattern, string, flags=0)

関数の引数の説明:

引数説明
patternマッチングする正規表現
stringマッチング対象の文字列。
flagsフラグ。正規表現のマッチング方法を制御します。例: 大文字と小文字を区別するかどうか、複数行マッチングなど。参照:正規表現修飾子 - オプションフラグ

マッチングが成功すると re.match メソッドはマッチオブジェクトを返し、そうでない場合は None を返します。

group(num) または groups() マッチオブジェクト関数を使用して、マッチした式を取得できます。

マッチオブジェクトのメソッド説明
group(num=0)マッチした式全体の文字列。group() には一度に複数のグループ番号を入力でき、その場合、それらのグループに対応する値を含むタプルを返します。
groups()1 から含まれるグループ番号までのすべてのグループ文字列を含むタプルを返します。

例

#!/usr/bin/python # -*- coding: UTF-8 -*- import re print(re.match('www', 'www.example.com').span()) # 先頭位置でマッチング print(re.match('com', 'www.example.com')) # 先頭位置ではない場合のマッチング

上記の例の実行出力結果は次のとおりです:

(0, 3)
None

例

#!/usr/bin/python import re line = "Cats are smarter than dogs" matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I) if matchObj: print "matchObj.group() : ", matchObj.group() print "matchObj.group(1) : ", matchObj.group(1) print "matchObj.group(2) : ", matchObj.group(2) else: print "No match!!"

上記の例の実行結果は次のとおりです:

matchObj.group() :  Cats are smarter than dogs
matchObj.group(1) :  Cats
matchObj.group(2) :  smarter

re.search メソッド

re.search は文字列全体をスキャンし、最初に成功したマッチを返します。

関数構文:

re.search(pattern, string, flags=0)

関数の引数の説明:

引数説明
patternマッチングする正規表現
stringマッチング対象の文字列。
flagsフラグ。正規表現のマッチング方法を制御します。例: 大文字と小文字を区別するかどうか、複数行マッチングなど。

マッチングが成功すると re.search メソッドはマッチオブジェクトを返し、そうでない場合は None を返します。

group(num) または groups() マッチオブジェクト関数を使用して、マッチした式を取得できます。

マッチオブジェクトのメソッド説明
group(num=0)マッチした式全体の文字列。group() には一度に複数のグループ番号を入力でき、その場合、それらのグループに対応する値を含むタプルを返します。
groups()1 から含まれるグループ番号までのすべてのグループ文字列を含むタプルを返します。

例

#!/usr/bin/python # -*- coding: UTF-8 -*- import re print(re.search('www', 'www.example.com').span()) # 先頭位置でマッチング print(re.search('com', 'www.example.com').span()) # 先頭位置ではない場合のマッチング

上記の例の実行出力結果は次のとおりです:

(0, 3)
(11, 14)

例

#!/usr/bin/python import re line = "Cats are smarter than dogs"; searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I) if searchObj: print "searchObj.group() : ", searchObj.group() print "searchObj.group(1) : ", searchObj.group(1) print "searchObj.group(2) : ", searchObj.group(2) else: print "Nothing found!!"
上記の例の実行結果は次のとおりです:
searchObj.group() :  Cats are smarter than dogs
searchObj.group(1) :  Cats
searchObj.group(2) :  smarter

re.match と re.search の違い

re.match は文字列の先頭のみをマッチングします。文字列の先頭が正規表現に一致しない場合、マッチングは失敗し、関数は None を返します。一方、re.search はマッチが見つかるまで文字列全体をマッチングします。

例

#!/usr/bin/python import re line = "Cats are smarter than dogs"; matchObj = re.match( r'dogs', line, re.M|re.I) if matchObj: print "match --> matchObj.group() : ", matchObj.group() else: print "No match!!" matchObj = re.search( r'dogs', line, re.M|re.I) if matchObj: print "search --> searchObj.group() : ", matchObj.group() else: print "No match!!"
上記の例の実行結果は次のとおりです:
No match!!
search --> searchObj.group() :  dogs

検索と置換

Python の re モジュールは、文字列内のマッチした部分を置換する re.sub を提供します。

構文:

re.sub(pattern, repl, string, count=0, flags=0)

引数:

  • pattern : 正規表現のパターン文字列。
  • repl : 置換する文字列。関数にすることもできます。
  • string : 検索および置換の対象となる元の文字列。
  • count : パターンマッチ後の最大置換回数。デフォルトの 0 はすべてのマッチを置換することを意味します。

例

#!/usr/bin/python # -*- coding: UTF-8 -*- import re phone = "2004-959-559 # これは外国の電話番号です" # 文字列中の Python コメントを削除 num = re.sub(r'#.*$', "", phone) print "電話番号は:", num # 数字以外の文字列を削除 num = re.sub(r'\D', "", phone) print "電話番号は :", num
上記の例の実行結果は次のとおりです:
电话号码是:  2004-959-559 
电话号码是 :  2004959559

repl 引数は関数です

次の例では、文字列内のマッチした数字を 2 倍にします:

例

#!/usr/bin/python # -*- coding: UTF-8 -*- import re # マッチした数字を 2 倍にする def double(matched): value = int(matched.group('value')) return str(value * 2) s = 'A23G4HFD567' print(re.sub('(?P<value>\d+)', double, s))

実行出力結果は次のとおりです:

A46G8HFD1134

re.compile 関数

compile 関数は正規表現をコンパイルして正規表現(Pattern)オブジェクトを生成し、match()、search()、findall などの関数で使用できます。

構文形式は次のとおりです:

re.compile(pattern[, flags])

引数:

  • pattern: 文字列形式の正規表現

  • flags: オプションで、マッチングモードを指定します。例えば大文字小文字の無視、複数行モードなどです。具体的な引数は次のとおりです:

    1. re.I大文字と小文字を無視
    2. re.L特殊文字セット \w, \W, \b, \B, \s, \S が現在の環境に依存することを示します
    3. re.M複数行モード
    4. re.Sすなわち.改行文字を含む任意の文字(.改行文字を含まない)
    5. re.U特殊文字セット \w, \W, \b, \B, \d, \D, \s, \S が Unicode 文字属性データベースに依存することを示します
    6. re.X読みやすくするために、スペースと#後ろのコメントを無視します

例

例

>>>import re >>> pattern = re.compile(r'\d+') # 少なくとも1つの数字にマッチさせる >>> m = pattern.match('one12twothree34four') # 先頭を検索、マッチなし >>> print m None >>> m = pattern.match('one12twothree34four', 2, 10) # 'e' の位置からマッチング、マッチなし >>> print m None >>> m = pattern.match('one12twothree34four', 3, 10) # '1' の位置からマッチング、ちょうどマッチ >>> print m # Match オブジェクトを返す <_sre.SRE_Match object at 0x10a42aac0> >>> m.group(0) # 0 は省略可能 '12' >>> m.start(0) # 0 は省略可能 3 >>> m.end(0) # 0 は省略可能 5 >>> m.span(0) # 0 は省略可能 (3, 5)

上記では、マッチングが成功すると Match オブジェクトが返されます。そのうち:

  • group([group1, …])メソッドは、1つ以上のグループにマッチした文字列を取得するために使用します。マッチした部分文字列全体を取得したい場合は、直接使用できます。group() 或 group(0);
  • start([group])メソッドは、グループにマッチした部分文字列の文字列全体における開始位置(部分文字列の最初の文字のインデックス)を取得するために使用します。引数のデフォルト値は 0 です;
  • end([group])メソッドは、グループにマッチした部分文字列の文字列全体における終了位置(部分文字列の最後の文字のインデックス+1)を取得するために使用します。引数のデフォルト値は 0 です;
  • span([group])メソッドは戻り値を返します(start(group), end(group))。

もう一つ例を見てみましょう:

例

>>>import re >>> pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I) # re.I は大文字小文字を無視することを示します >>> m = pattern.match('Hello World Wide Web') >>> print m # マッチング成功、Match オブジェクトを返す <_sre.SRE_Match object at 0x10bea83e8> >>> m.group(0) # マッチ成功した部分文字列全体を返す 'Hello World' >>> m.span(0) # マッチ成功した部分文字列全体のインデックスを返す (0, 11) >>> m.group(1) # 最初のグループがマッチした部分文字列を返す 'Hello' >>> m.span(1) # 最初のグループがマッチした部分文字列のインデックスを返す (0, 5) >>> m.group(2) # 2番目のグループがマッチした部分文字列を返す 'World' >>> m.span(2) # 2番目のグループがマッチした部分文字列を返す (6, 11) >>> m.groups() # (m.group(1), m.group(2), ...) と同等 ('Hello', 'World') >>> m.group(3) # 3番目のグループは存在しない Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: no such group

findall

文字列内で正規表現にマッチするすべての部分文字列を検索し、リストを返します。複数のマッチングパターンがある場合はタプルのリストを返し、マッチするものが見つからない場合は空のリストを返します。

注意:match と search は1回だけマッチし、findall はすべてにマッチします。

構文形式は次のとおりです:

findall(string[, pos[, endpos]])

パラメータ:

  • string: マッチ対象の文字列。
  • pos: オプションのパラメータで、文字列の開始位置を指定します。デフォルトは 0 です。
  • endpos: オプションのパラメータで、文字列の終了位置を指定します。デフォルトは文字列の長さです。

文字列内のすべての数字を検索します:

例

# -*- coding:UTF8 -*- import re pattern = re.compile(r'\d+') # 数字を検索 result1 = pattern.findall('サンプル 123 google 456') result2 = pattern.findall('run88oob123google456', 0, 10) print(result1) print(result2)

出力結果:

['123', '456']
['88', '12']

複数のマッチングパターンの場合、タプルのリストを返します:

例

import re

result = re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')
print(result)
[('width', '20'), ('height', '10')]

re.finditer

findall と似ており、文字列内で正規表現にマッチするすべての部分文字列を検索し、それらをイテレータとして返します。

re.finditer(pattern, string, flags=0)

パラメータ:

パラメータ説明
patternマッチする正規表現
stringマッチ対象の文字列。
flagsフラグ。正規表現のマッチング方法を制御するために使用します。例:大文字小文字を区別するかどうか、複数行マッチングなど。参照:正規表現修飾子 - オプションフラグ

例

# -*- coding: UTF-8 -*- import re it = re.finditer(r"\d+","12a32bc43jf3") for match in it: print (match.group() )

出力結果:

12 
32 
43 
3

re.split

split メソッドは、マッチする部分文字列に従って文字列を分割し、リストを返します。その使用形式は次のとおりです:

re.split(pattern, string[, maxsplit=0, flags=0])

パラメータ:

パラメータ説明
patternマッチする正規表現
stringマッチ対象の文字列。
maxsplit分割回数。maxsplit=1 は1回分割します。デフォルトは 0 で、回数は制限されません。
flagsフラグ。正規表現のマッチング方法を制御するために使用します。例:大文字小文字を区別するかどうか、複数行マッチングなど。参照:正規表現修飾子 - オプションフラグ

例

>>>import re >>> re.split('\W+', 'サンプル, サンプル, サンプル.') ['サンプル', 'サンプル', 'サンプル', ''] >>> re.split('(\W+)', ' サンプル, サンプル, サンプル.') ['', ' ', 'サンプル', ', ', 'サンプル', ', ', 'サンプル', '.', ''] >>> re.split('\W+', ' サンプル, サンプル, サンプル.', 1) ['', 'サンプル, サンプル, サンプル.'] >>> re.split('a*', 'hello world') # マッチする文字列が見つからない場合、split はその文字列を分割しません。 ['hello world']

正規表現オブジェクト

re.RegexObject

re.compile() は RegexObject オブジェクトを返します。

re.MatchObject

group() は RE にマッチした文字列を返します。

  • start()マッチの開始位置を返します
  • end()マッチの終了位置を返します
  • span()マッチの (開始, 終了) 位置を含むタプルを返します

正規表現修飾子 - オプションフラグ

正規表現には、マッチングのパターンを制御するためのオプションのフラグ修飾子を含めることができます。修飾子はオプションのフラグとして指定されます。複数のフラグは、ビット単位の OR(|) で指定できます。例:re.I | re.M は I フラグと M フラグを設定します。

修飾子説明
re.Iマッチングで大文字と小文字を区別しないようにします
re.Lローカライズ認識(locale-aware)のマッチングを行います
re.M複数行マッチング。^ と $ に影響します
re.S. が改行を含むすべての文字にマッチするようにします
re.UUnicode 文字セットに基づいて文字を解析します。このフラグは \w, \W, \b, \B に影響します。
re.Xこのフラグは、より柔軟な形式を提供することで、正規表現をより理解しやすく書けるようにします。

正規表現パターン

パターン文字列は、特別な構文を使用して正規表現を表します:

文字と数字はそれ自身を表します。正規表現パターン内の文字と数字は、同じ文字列にマッチします。

多くの文字と数字は、前にバックスラッシュを付けると異なる意味を持ちます。

句読点は、エスケープされた場合にのみそれ自身にマッチします。そうでなければ特別な意味を表します。

バックスラッシュ自体は、バックスラッシュでエスケープする必要があります。

正規表現は通常バックスラッシュを含むため、それらを表すには raw 文字列を使用するのが最善です。パターン要素(r'\t' など、'\\t' と同等)は対応する特殊文字にマッチします。

次の表は、正規表現パターン構文の特殊要素を示しています。パターンと同時にオプションのフラグパラメータを提供すると、一部のパターン要素の意味が変わります。

パターン説明
^文字列の先頭にマッチします
$文字列の末尾にマッチします。
.改行を除く任意の文字にマッチします。re.DOTALL フラグが指定されると、改行を含む任意の文字にマッチできます。
[...]文字のグループを表すために使用され、個別に列挙します:[amk] は 'a'、'm'、または 'k' にマッチします。
[^...][] 内にない文字:[^abc] は a、b、c 以外の文字にマッチします。
re*0個以上の式にマッチします。
re+1個以上の式にマッチします。
re?直前の正規表現で定義されたフラグメントの0個または1個にマッチします。非貪欲な方法です。
re{ n}直前の式の n 個に正確にマッチします。例:o{2}"Bob" の "o" にはマッチしませんが、"food" の2つの o にはマッチします。
re{ n,}直前の式の n 個にマッチします。例:o{2,} は "Bob" の "o" にはマッチしませんが、"foooood" のすべての o にはマッチします。"o{1,}" は "o+" と同等です。"o{0,}" は "o*" と同等です。
re{ n, m}直前の正規表現で定義されたフラグメントの n 回から m 回にマッチします。貪欲な方法です。
a| ba または b にマッチします
(re)正規表現をグループ化し、マッチしたテキストを記憶します
(?imx)正規表現には i、m、または x の3つのオプションフラグを含められます。括弧内の領域にのみ影響します。
(?-imx)正規表現の i、m、または x オプションフラグをオフにします。括弧内の領域にのみ影響します。
(?: re)(...) に似ていますが、グループを表しません
(?imx: re)括弧内で i、m、または x オプションフラグを使用します
(?-imx: re)括弧内で i、m、または x オプションフラグを使用しません
(?#...)コメント。
(?= re)前方肯定の先読み断言。含まれる正規表現が ... で表され、現在位置でマッチに成功すると成功し、そうでなければ失敗します。ただし、含まれる式が試行された後、マッチングエンジンは位置を進めません。パターンの残りの部分は、先読みの右側で試行されます。
(?! re)前方否定の先読み断言。肯定の先読みとは逆です。含まれる式が文字列の現在位置でマッチできない場合に成功します。
(?> re)独立したマッチングパターンで、バックトラッキングを省きます。
\w英数字およびアンダースコアにマッチします
\W英数字およびアンダースコア以外にマッチします
\s任意の空白文字にマッチします。次と同等です:[ \t\n\r\f]。
\S任意の非空白文字にマッチします
\d任意の数字にマッチします。[0-9] と同等です。
\D任意の非数字にマッチします
\A文字列の先頭にマッチします
\Z文字列の末尾にマッチします。改行がある場合、改行前の末尾文字列にのみマッチします。
\z文字列の末尾にマッチします
\G最後のマッチが完了した位置にマッチします。
\b単語の境界にマッチします。つまり、単語とスペースの間の位置です。例:'er\b' は "never" の 'er' にマッチしますが、"verb" の 'er' にはマッチしません。
\B非単語境界にマッチします。'er\B' は "verb" の 'er' にマッチしますが、"never" の 'er' にはマッチしません。
\n, \t など。改行文字にマッチします。タブ文字にマッチします。など
\1...\9n 番目のグループの内容にマッチします。
\10n 番目のグループの内容にマッチします(マッチしている場合)。そうでない場合は、8進数の文字コードを表す式を指します。

正規表現の例

文字マッチング

例説明
python"python" にマッチします。

文字クラス

例説明
[Pp]ython "Python" または "python" にマッチします
rub[ye]"ruby" または "rube" にマッチします
[aeiou]角括弧内の任意の1文字にマッチします
[0-9]任意の数字にマッチします。
[a-z]任意の小文字にマッチします
[A-Z]任意の大文字にマッチします
[a-zA-Z0-9]任意の英字および数字にマッチします
[^aeiou]aeiou の文字以外のすべての文字
[^0-9]数字以外の文字にマッチします

特殊文字クラス

例説明
."\n" 以外の任意の1文字にマッチします。'\n' を含む任意の文字にマッチするには、'[.\n]' のようなパターンを使用してください。
\d1つの数字文字にマッチします。[0-9] と同等です。
\D 1つの非数字文字にマッチします。[^0-9] と同等です。
\sスペース、タブ、フォームフィードなどを含む任意の空白文字にマッチします。[ \f\n\r\t\v] と同等です。
\S 任意の非空白文字にマッチします。[^ \f\n\r\t\v] と同等です。
\wアンダースコアを含む任意の単語文字にマッチします。'[A-Za-z0-9_]' と同等です。
\W任意の非単語文字にマッチします。'[^A-Za-z0-9_]' と同等です。
その他の拡張