Python正規表現マスターガイド:実践的パターンマッチング
正規表現とは
正規表現は、特殊な構文をパターンとして保持し、他の文字列や文字列セットとのマッチングや検索を支援する特殊な文字シーケンスです。正規表現はUNIXの世界で広く使用されています。
Pythonのreモジュールは、Perlライクな正規表現を完全にサポートしています。正規表現のコンパイルや使用中にエラーが発生した場合、reモジュールはre.error例外を発生させます。
正規表現を扱う2つの重要な関数を説明しますが、まず最初に:正規表現で使用すると特殊な意味を持つさまざまな文字があります。正規表現を扱う際の混乱を避けるため、Raw Strings(r'expression')を使用します。
match関数
この関数は、オプションのflagsを指定して、RE patternをstringの先頭からマッチさせようとします。
構文
re.match(pattern, string, flags=0)
パラメータ
| No. | パラメータと説明 |
|---|---|
| 1 | pattern - マッチさせる正規表現 |
| 2 | string - パターンを文字列の先頭から検索対象とする文字列 |
| 3 | flags - ビットごとのOR(|)で異なるフラグを指定可能。以下のテーブルにリストされている修飾子 |
re.match関数は、成功時にmatchオブジェクトを、失敗時にNoneを返します。matchオブジェクトのgroup(num)またはgroups()関数を使用してマッチした式を取得します。
| No. | Matchオブジェクトのメソッドと説明 |
|---|---|
| 1 | group(num=0) - マッチ全体(または特定のサブグループnum)を返す |
| 2 | groups() - すべてのマッチしたサブグループをタプルで返す(なければ空タプル) |
例
#!/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
search関数
この関数は、オプションのflagsを指定して、RE patternの最初の出現をstring内のどこでも検索します。
構文
re.search(pattern, string, flags=0)
パラメータ
| No. | パラメータと説明 |
|---|---|
| 1 | pattern - マッチさせる正規表現 |
| 2 | string - 文字列のどこでもパターンを検索対象とする文字列 |
| 3 | flags - ビットごとのOR(|)で異なるフラグを指定可能。以下のテーブルにリストされている修飾子 |
re.search関数は、成功時にmatchオブジェクトを、失敗時にNoneを返します。matchオブジェクトのgroup(num)またはgroups()関数を使用してマッチした式を取得します。
| No. | Matchオブジェクトのメソッドと説明 |
|---|---|
| 1 | group(num=0) - マッチ全体(または特定のサブグループnum)を返す |
| 2 | groups() - すべてのマッチしたサブグループをタプルで返す(なければ空タプル) |
例
#!/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
マッチングとサーチングの違い
Pythonは正規表現に基づく2つの異なるプリミティブ操作を提供します:matchは文字列の先頭でのみマッチをチェックし、searchは文字列のどこでもマッチをチェックします(これはPerlのデフォルト動作です)。
例
#!/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!!")
searchObj = re.search(r'dogs', line, re.M|re.I)
if searchObj:
print("search --> searchObj.group() : ", searchObj.group())
else:
print("Nothing found!!")
実行結果:
No match!!
search --> searchObj.group() : dogs
検索と置換
正規表現を使用するreモジュールの最も重要なメソッドの1つはsubです。
構文
re.sub(pattern, repl, string, max=0)
このメソッドは、string内のRE patternのすべての出現をreplで置換します。maxが指定されない限りすべての出現を置換します。変更後の文字列を返します。
例
#!/usr/bin/python
import re
phone = "2004-959-559 # This is Phone Number"
# Pythonスタイルのコメントを削除
num = re.sub(r'#.*$', "", phone)
print("Phone Num : ", num)
# 数字以外を削除
num = re.sub(r'\D', "", phone)
print("Phone Num : ", num)
実行結果:
Phone Num : 2004-959-559
Phone Num : 2004959559
正規表現修飾子:オプションフラグ
正規表現リテラルには、マッチングのさまざまな側面を制御するオプションの修飾子を含められます。修飾子はオプションのフラグとして指定されます。前述のように排他的OR(|)で複数の修飾子を指定でき、以下のいずれかで表現されます。
| No. | 修飾子と説明 |
|---|---|
| 1 | re.I - 大文字小文字を区別しないマッチングを実行 |
| 2 | re.L - 現在のロケールに従って単語を解釈。アルファベットグループ(\wと\W)、単語境界(\bと\B)の動作に影響 |
| 3 | re.M - $を行末(文字列末尾だけでなく)に、^を行頭(文字列先頭だけでなく)にマッチさせる |
| 4 | re.S - ピリオド(ドット)が改行文字を含むすべての文字にマッチするようにする |
| 5 | re.U - Unicode文字セットに従って文字を解釈。\w、\W、\b、\Bの動作に影響 |
| 6 | re.X - 「きれいな」正規表現構文を許可。ホワイトスペースを無視(セット[]内やバックスラッシュでエスケープされている場合を除く)、エスケープされていない#をコメントマーカーとして扱う |
正規表現パターン
制御文字(+ ? . * ^ $ ( ) [ ] { } | \)を除き、すべての文字はそれ自体にマッチします。制御文字はバックスラッシュを前に付けることでエスケープできます。
Pythonで利用可能な正規表現構文を以下の表にまとめます。
| No. | パターンと説明 |
|---|---|
| 1 | ^ - 行の先頭にマッチ |
| 2 | $ - 行の末尾にマッチ |
| 3 | . - 改行以外の任意の1文字にマッチ。mオプション使用で改行にもマッチ |
| 4 | [...] - ブラケット内の任意の1文字にマッチ |
| 5 | [^...] - ブラケット内にない任意の1文字にマッチ |
| 6 | re* - 直前の式の0回以上の繰り返しにマッチ |
| 7 | re+ - 直前の式の1回以上の繰り返しにマッチ |
| 8 | re? - 直前の式の0回または1回の出現にマッチ |
| 9 | re{n} - 直前の式のちょうどn回の出現にマッチ |
| 10 | re{n,} - 直前の式のn回以上の出現にマッチ |
| 11 | re{n,m} - 直前の式の少なくともn回、最大m回の出現にマッチ |
| 12 | a|b - aまたはbにマッチ |
| 13 | (re) - 正規表現をグループ化し、マッチしたテキストを記憶 |
| 14 | (?imx) - 正規表現内でi、m、xオプションを一時的にオン。括弧内ならその領域のみ影響 |
| 15 | (?-imx) - 正規表現内でi、m、xオプションを一時的にオフ。括弧内ならその領域のみ影響 |
| 16 | (?:re) - 正規表現をグループ化するが、マッチしたテキストを記憶しない |
| 17 | (?imx:re) - 括弧内でi、m、xオプションを一時的にオン |
| 18 | (?-imx:re) - 括弧内でi、m、xオプションを一時的にオフ |
| 19 | (?#...) - コメント |
| 20 | (?=re) - パターンを使用して位置を指定。範囲を持たない |
| 21 | (?!re) - パターンの否定を使用して位置を指定。範囲を持たない |
| 22 | (?>re) - バックトラックなしで独立パターンにマッチ |
| 23 | \w - 単語文字にマッチ |
| 24 | \W - 非単語文字にマッチ |
| 25 | \s - ホワイトスペースにマッチ。[\t\n\r\f]と等価 |
| 26 | \S - 非ホワイトスペースにマッチ |
| 27 | \d - 数字にマッチ。[0-9]と等価 |
| 28 | \D - 非数字にマッチ |
| 29 | \A - 文字列の先頭にマッチ |
| 30 | \Z - 文字列の末尾にマッチ。改行が存在すればその直前 |
| 31 | \z - 文字列の末尾にマッチ |
| 32 | \G - 最後のマッチが終了した位置にマッチ |
| 33 | \b - 括弧外では単語境界にマッチ。括弧内ではバックスペース(0x08)にマッチ |
| 34 | \B - 非単語境界にマッチ |
| 35 | \n, \t, etc. - 改行、キャリッジリターン、タブ等にマッチ |
| 36 | \1...\9 - n番目のグループ化された部分配現にマッチ |
| 37 | \10 - 既にマッチしていればn番目のグループ化された部分配現、そうでなければ文字コードの8進表現を参照 |
正規表現の例
リテラル文字
| No. | 例と説明 |
|---|---|
| 1 | python - "python"にマッチ |
文字クラス
| No. | 例と説明 |
|---|---|
| 1 | [Pp]ython - "Python"または"python"にマッチ |
| 2 | rub[ye] - "ruby"または"rube"にマッチ |
| 3 | [aeiou] - 任意の小文字母音1文字にマッチ |
| 4 | [0-9] - 任意の数字にマッチ;[0123456789]と同等 |
| 5 | [a-z] - 任意の小文字ASCII文字にマッチ |
| 6 | [A-Z] - 任意の大文字ASCII文字にマッチ |
| 7 | [a-zA-Z0-9] - 上記すべてにマッチ |
| 8 | [^aeiou] - 小文字母音以外にマッチ |
| 9 | [^0-9] - 数字以外にマッチ |
特殊文字クラス
| No. | 例と説明 |
|---|---|
| 1 | . - 改行以外の任意の文字にマッチ |
| 2 | \d - 数字にマッチ:[0-9] |
| 3 | \D - 非数字にマッチ:[^0-9] |
| 4 | \s - ホワイトスペース文字にマッチ:[ \t\r\n\f] |
| 5 | \S - 非ホワイトスペースにマッチ:[^ \t\r\n\f] |
| 6 | \w - 単語文字1つにマッチ:[A-Za-z0-9_] |
| 7 | \W - 非単語文字にマッチ:[^A-Za-z0-9_] |
繰り返しのケース
| No. | 例と説明 |
|---|---|
| 1 | ruby? - "rub"または"ruby"にマッチ:yはオプション |
| 2 | ruby* - "rub"に続く0個以上のyにマッチ |
| 3 | ruby+ - "rub"に続く1個以上のyにマッチ |
| 4 | \d{3} - ちょうど3桁の数字にマッチ |
| 5 | \d{3,} - 3桁以上の数字にマッチ |
| 6 | \d{3,5} - 3、4、または5桁の数字にマッチ |
非貪欲繰り返し
最小の繰り返し回数にマッチします。
| No. | 例と説明 |
|---|---|
| 1 | <.*> - 貪欲繰り返し:"<python>perl>"にマッチ |
| 2 | <.*?> - 非貪欲:"<python>perl>"内の"<python>"にマッチ |
括弧によるグループ化
| No. | 例と説明 |
|---|---|
| 1 | \D\d+ - グループなし:+は\dを繰り返す |
| 2 | (\D\d)+ - グループ化:+\D\dの組み合わせを繰り返す |
| 3 | ([Pp]ython(, )?)+ - "Python"、"Python, python, python"等にマッチ |
後方参照
以前にマッチしたグループを再度マッチさせます。
| No. | 例と説明 |
|---|---|
| 1 | ([Pp])ython&\1ails - "python&pails"または"Python&Pails"にマッチ |
| 2 | (['"])[^\1]*\1 - シングルまたはダブルクォート文字列。\1は最初のグループがマッチしたものにマッチ。\2は2番目のグループがマッチしたものにマッチ、等 |
選択肢
| No. | 例と説明 |
|---|---|
| 1 | python|perl - "python"または"perl"にマッチ |
| 2 | rub(y|le) - "ruby"または"ruble"にマッチ |
| 3 | Python(!+|\?) - "Python"に続く1個以上の!または1個の? |
アンカー
マッチ位置を指定する必要があります。
| No. | 例と説明 |
|---|---|
| 1 | ^Python - 文字列または内部行の先頭の"Python"にマッチ |
| 2 | Python$ - 文字列または行の末尾の"Python"にマッチ |
| 3 | \APython - 文字列の先頭の"Python"にマッチ |
| 4 | Python\Z - 文字列の末尾の"Python"にマッチ |
| 5 | \bPython\b - 単語境界の"Python"にマッチ |
| 6 | \brub\B - \Bは非単語境界:"rube"と"ruby"の"rub"にマッチするが単独ではマッチしない |
| 7 | Python(?=!) - 感嘆符が続く場合のみ"Python"にマッチ |
| 8 | Python(?!) - 感嘆符が続かない場合のみ"Python"にマッチ |
括弧を使った特殊構文
| No. | 例と説明 |
|---|---|
| 1 | R(?#comment) - "R"にマッチ。以降はコメント |
| 2 | R(?i)uby - "uby"マッチ時のみ大文字小文字無視 |
| 3 | R(?i:uby) - 上記と同じ |
| 4 | rub(?:y|le) - \1バックリファレンスを作成せずにグループ化のみ |
Python
- C#正規表現:Regexクラスとパターンマッチング実践ガイド
- Python データ型マスター: 実践ガイド
- Python 演算子完全マスター: 包括的ガイド
- Python pass文完全マスター: 実践ガイド
- Python 関数引数完全マスター: 位置引数・キーワード引数・デフォルト引数
- Python辞書完全ガイド:作成、操作、高度なテクニック
- Pythonイテレータ完全ガイド:仕組みと自作方法
- Pythonクロージャ解説:ネスト関数が変数を捕捉する仕組み
- Python正規表現(reモジュール)実践ガイド
- Python datetimeマスター:日付・時刻・タイムゾーン実践ガイド
- Java正規表現: java.util.regexでパターンマッチングをマスターする