正規表現の仕組みを復習する必要がある場合は、まずインタラクティブチュートリアルをご覧ください。
Python は、すべての Python インストールにバンドルされている標準の Python ライブラリ re を通じて正規表現をサポートしています。このライブラリは PCRE と完全に互換性があるわけではありませんが、正規表現の一般的なユースケースの大部分をサポートしています。
このリファレンスは Python 3 用です。まだ更新していない場合は、Python 2 ページを参照してください。
Python で正規表現を記述する場合、通常の Python 文字列の代わりに raw 文字列を使用することをお勧めします。生の文字列は特別なプレフィックス(r)で始まり、Python にバックスラッシュや文字列内の特殊なメタ文字を解釈しないように指示し、正規表現エンジンに直接渡すことができます。
これは、"\n\w" のようなパターンが解釈されず、他の言語のように "\\n\\w" ではなく r"\n\w" と記述できることを意味し、はるかに読みやすくなります。
re パッケージには多くのトップレベルメソッドがあり、Python で正規表現が特定の文字列と一致するかどうかをテストするには、re.search() を使用できます。このメソッドは、パターンが一致しない場合は None を返し、一致した文字列の部分に関する追加情報を含む re.MatchObject を返します。
このメソッドは最初の一致の後で停止することに注意してください。そのため、データの抽出よりも正規表現のテストに適しています。
matchObject = re.search(パターン, input_str, flags=0)
import re # 正規表現を使用して日付文字列に一致させましょう。 # 出力は無視します。正規表現が一致するかどうかだけをテストしているためです。 regex = r"([a-zA-Z]+) (\d+)" if re.search(regex, "June 24"): # 確かに、式 "([a-zA-Z]+) (\d+)" は日付文字列と一致します。 # 必要に応じて、MatchObject の start() メソッドと end() メソッドを使用して # 入力文字列内のパターンの位置を取得し、 # group() メソッドを使用してすべての一致とキャプチャされたグループを取得できます。 match = re.search(regex, "June 24") # 文字列の先頭と末尾で一致するため、[0, 7) が出力されます。 print("インデックス %s、%s で一致" % (match.start(), match.end())) # グループには一致した値が含まれています。特に: # match.group(0) は常に完全に一致した文字列を返します # match.group(1)、match.group(2)、... はキャプチャされた # グループを入力文字列の左から右の順に返します # match.group() は match.group(0) と同等です # したがって、これは "June 24" を出力します print("完全一致: %s" % (match.group(0))) # したがって、これは "June" を出力します print("月: %s" % (match.group(1))) # したがって、これは "24" を出力します print("日: %s" % (match.group(2))) else: # re.search() が一致しない場合、None が返されます print("正規表現パターンは一致しません。 :(")
上記の re.search() メソッドとは異なり、re.findall() を使用して入力文字列全体をグローバル検索できます。パターンにキャプチャグループがある場合、キャプチャされたすべてのデータのリストを返しますが、そうでない場合は、一致自体のリスト、または一致が見つからない場合は空のリストを返します。
各一致に追加のコンテキストが必要な場合は、re.finditer() を使用できます。これは、代わりに re.MatchObjects のイテレータを返してウォークスルーします。どちらのメソッドも同じパラメータを取ります。
matchList = re.findall(パターン, input_str, flags=0)
matchList = re.finditer(パターン, input_str, flags=0)
import re # 正規表現を使用していくつかの日付文字列に一致させましょう。 regex = r"[a-zA-Z]+ \d+" matches = re.findall(regex, "June 24, August 9, Dec 12") for match in matches: # これは以下を出力します: # June 24 # August 9 # Dec 12 print("完全一致: %s" % (match)) # 各日付の特定の月をキャプチャするには、次のパターンを使用できます regex = r"([a-zA-Z]+) \d+" matches = re.findall(regex, "June 24, August 9, Dec 12") for match in matches: # これは以下を出力します: # June # August # Dec print("一致月: %s" % (match)) # 各一致の正確な位置が必要な場合 regex = r"([a-zA-Z]+) \d+" matches = re.finditer(regex, "June 24, August 9, Dec 12") for match in matches: # これは以下を出力します: # 0 7 # 9 17 # 19 25 # これは、入力文字列内の各一致の開始と終了に対応しています print("インデックスで一致: %s, %s" % (match.start(), match.end()))
もう1つの一般的なタスクは、正規表現を使用して文字列の一部を検索して置換することです。たとえば、古いメールドメインのすべてのインスタンスを置換したり、テキストの順序を入れ替えたりすることです。 Python では、re.sub() メソッドを使用してこれを行うことができます。
オプションの count 引数は、入力文字列で行う置換の正確な数であり、この値が 0 以下の場合、文字列内のすべての一致が置換されます。
replacedString = re.sub(パターン, replacement_pattern, input_str, count, flags=0)
import re # 日日付文字列の日と月の順序を逆にしてみましょう。 # 置換文字列にもメタ文字が含まれていることに注意してください # (キャプチャされたグループへの逆参照)なので、 # それにも raw 文字列を使用します。 regex = r"([a-zA-Z]+) (\d+)" # これは文字列の順序を変更し、以下を出力します: # 24 of June, 9 of August, 12 of Dec print(re.sub(regex, r"\2 of \1", "June 24, August 9, Dec 12"))
re フラグ上記の Python 正規表現メソッドでは、それぞれにオプションの flags 引数もあることに気付くでしょう。使用可能なフラグのほとんどは便宜上のものであり、正規表現自体に直接書き込むことができますが、場合によっては役立つものもあります。
re.IGNORECASE は、パターンを大文字と小文字を区別しないようにし、大文字と小文字が異なる文字列にも一致するようにします。re.MULTILINE は、入力文字列に改行文字(\n)が含まれている場合に必要です。このフラグを使用すると、開始メタ文字と終了メタ文字(それぞれ^ と $)が、入力文字列全体の先頭と末尾ではなく、各行の先頭と末尾に一致します。re.DOTALL は、ドット(.)メタ文字が改行文字(\n)を含むすべての文字に一致するようにします。Pythonでは、多くの文字列に一致する新しい正規表現パターンを作成すると処理速度が低下する可能性があります。そのため、同じ式を使用して多くの入力文字列をテストまたは情報抽出する必要がある場合は、パターンをコンパイルすることをお勧めします。このメソッドは、re.RegexObject を返します。
regexObject = re.compile(pattern, flags=0)
返されるオブジェクトは、上記と同じメソッドを持ちますが、入力文字列を受け取り、呼び出しごとにパターンまたはフラグを必要としなくなります。
import re # パターンを作成し、いくつかの情報を抽出します regex = re.compile(r"(\w+) World") result = regex.search("Hello World is the easiest") if result: # これは以下を出力します: # 0 11 # 一致の開始と終了位置 print(result.start(), result.end()) # これは以下を出力します: # Hello # Bonjour # 一致した各キャプチャグループについて for result in regex.findall("Hello World, Bonjour World"): print(result) # これは "World" を "Earth" に置き換え、以下を出力します: # Hello Earth print(regex.sub(r"\1 Earth", "Hello World"))
Pythonでの正規表現の使用に関する詳細については、以下のリンクをご覧ください。