[Python] 正規表現のパターンを変数に格納して使う方法

Pythonでは、正規表現のパターンを変数に格納して使用することが可能です。

正規表現を扱うためには、reモジュールをインポートします。

パターンを変数に格納し、その変数をreモジュールの関数(例: re.match()re.search())に渡すことで、正規表現を動的に利用できます。

例えば、pattern = r"\d+"のようにパターンを変数に格納し、re.search(pattern, text)のように使用します。

この記事でわかること
  • 正規表現パターンを変数に格納する方法
  • 動的にパターンを生成する技術
  • 複雑なパターンの再利用方法
  • 特定のデータを抽出する応用例

目次から探す

正規表現パターンを変数に格納する方法

パターンを変数に格納する基本的な方法

Pythonでは、正規表現のパターンを文字列として変数に格納することができます。

これにより、同じパターンを何度も使う際に便利です。

以下は、基本的な例です。

import re
# 正規表現パターンを変数に格納
pattern = r'\d+'  # 1つ以上の数字にマッチ

r(raw string)を使う理由

Pythonでは、正規表現のパターンを記述する際にrを前につけることで、raw string(生文字列)として扱うことができます。

これにより、エスケープシーケンスを気にせずに正規表現を書くことができ、可読性が向上します。

# 通常の文字列
pattern_normal = '\\d+'  # エスケープが必要
# raw string
pattern_raw = r'\d+'  # エスケープ不要

変数に格納したパターンをreモジュールで使用する方法

reモジュールを使用して、変数に格納した正規表現パターンを利用することができます。

以下のように、re.match(), re.search(), re.findall()などの関数で使用します。

import re
pattern = r'\d+'
text = "今日は2023年10月5日です。"
# パターンを使ってマッチを確認
match = re.match(pattern, text)

変数に格納したパターンを使ったre.match()の例

re.match()は、文字列の先頭からパターンにマッチするかを確認します。

以下はその例です。

import re
pattern = r'\d+'
text = "2023年10月5日です。"
# 先頭からマッチを確認
match = re.match(pattern, text)
if match:
    print("マッチしました:", match.group())
else:
    print("マッチしませんでした。")
マッチしました: 2023

変数に格納したパターンを使ったre.search()の例

re.search()は、文字列全体を検索し、パターンにマッチする部分を探します。

以下はその例です。

import re
pattern = r'\d+'
text = "今日は2023年10月5日です。"
# 文字列全体を検索
search = re.search(pattern, text)
if search:
    print("マッチしました:", search.group())
else:
    print("マッチしませんでした。")
マッチしました: 2023

変数に格納したパターンを使ったre.findall()の例

re.findall()は、文字列内のすべてのマッチをリストとして返します。

以下はその例です。

import re
pattern = r'\d+'
text = "今日は2023年10月5日です。"
# すべてのマッチをリストで取得
matches = re.findall(pattern, text)
print("マッチした数字:", matches)
マッチした数字: ['2023', '10', '5']

このように、正規表現のパターンを変数に格納することで、コードの可読性や再利用性が向上します。

動的に正規表現パターンを生成する方法

文字列の結合でパターンを動的に生成する

Pythonでは、文字列の結合を利用して動的に正規表現パターンを生成することができます。

これにより、特定の条件に応じたパターンを簡単に作成できます。

以下は、文字列の結合を使った例です。

import re
# 基本のパターン
base_pattern = r'\d{'
# 動的に数を指定
number = 3
dynamic_pattern = base_pattern + str(number) + r'}'
text = "1234 567 890"
# 動的に生成したパターンを使用
matches = re.findall(dynamic_pattern, text)
print("マッチした部分:", matches)
マッチした部分: ['123', '567', '890']

この例では、dynamic_patternr'\d{3}'となり、3桁の数字を探しています。ただし、3桁の数字の後が数字かどうかは判定していないため、1234から123を抽出しています。

ユーザー入力に基づいてパターンを生成する

ユーザーからの入力を基に正規表現パターンを生成することも可能です。

これにより、柔軟な検索が実現できます。

以下はその例です。

import re
# ユーザーからの入力を取得
user_input = input("検索したい数字の桁数を入力してください: ")
pattern = r'\d{' + user_input + r'}'
text = "1234 567 890"
# ユーザー入力に基づいて生成したパターンを使用
matches = re.findall(pattern, text)
print("マッチした部分:", matches)

このコードを実行すると、ユーザーが入力した桁数に応じた数字を検索します。

条件に応じて異なるパターンを選択する

条件に応じて異なる正規表現パターンを選択することもできます。

これにより、特定の状況に応じた検索が可能になります。

以下はその例です。

import re
# 条件に応じたパターンを選択
condition = "email"  # 例: "email" または "phone"
if condition == "email":
    pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
elif condition == "phone":
    pattern = r'\d{3}-\d{4}-\d{4}'
else:
    pattern = r'\d+'
text = "私のメールは example@example.com です。"
# 条件に応じて選択したパターンを使用
matches = re.findall(pattern, text)
print("マッチした部分:", matches)
マッチした部分: ['example@example.com']

この例では、条件に応じてメールアドレスのパターンを選択し、テキスト内からマッチする部分を抽出しています。

条件を変更することで、異なるパターンを簡単に適用できます。

正規表現パターンを再利用する方法

re.compile()を使ってパターンを再利用する

Pythonのreモジュールには、正規表現パターンをコンパイルして再利用するためのre.compile()関数があります。

この関数を使用することで、同じパターンを何度も使用する際に、毎回パターンを解析する必要がなくなります。

import re
# 正規表現パターンをコンパイル
pattern = re.compile(r'\d+')

re.compile()のメリットとパフォーマンス向上

re.compile()を使用する主なメリットは、パターンの解析を一度だけ行うため、パフォーマンスが向上することです。

特に、同じパターンを何度も使用する場合、コンパイルされたオブジェクトを使うことで、処理速度が速くなります。

また、可読性も向上し、コードがすっきりします。

# コンパイルしたパターンを使ってマッチを確認
text = "今日は2023年10月5日です。"
match = pattern.search(text)

re.compile()を使った具体例

以下は、re.compile()を使って正規表現パターンを再利用する具体例です。

この例では、複数のテキストに対して同じパターンを適用しています。

import re
# 正規表現パターンをコンパイル
pattern = re.compile(r'\d+')
texts = [
    "今日は2023年10月5日です。",
    "明日は2023年10月6日です。",
    "2023年の最後の月は12月です。"
]
# 各テキストに対してマッチを確認
for text in texts:
    match = pattern.findall(text)
    print(f"'{text}' のマッチした数字:", match)
'今日は2023年10月5日です。' のマッチした数字: ['2023', '10', '5']
'明日は2023年10月6日です。' のマッチした数字: ['2023', '10', '6']
'2023年の最後の月は12月です。' のマッチした数字: ['2023', '12']

このように、re.compile()を使用することで、同じ正規表現パターンを効率的に再利用し、コードの可読性とパフォーマンスを向上させることができます。

応用例:複雑なパターンを変数に格納して使う

複数のパターンを組み合わせて使う

複数の正規表現パターンを組み合わせることで、より複雑な検索が可能になります。

例えば、数字と文字列の両方を同時に検索する場合、以下のようにパターンを組み合わせることができます。

import re
# 数字またはアルファベットのパターンを組み合わせ
pattern = r'(\d+|[a-zA-Z]+)'
text = "abc 123 xyz 456"
# パターンを使ってマッチを確認
matches = re.findall(pattern, text)
print("マッチした部分:", matches)
マッチした部分: ['abc', '123', 'xyz', '456']

特定の文字列パターンを抽出する

特定の文字列パターンを抽出するために、正規表現を使用することができます。

例えば、特定の単語を含む文を抽出する場合、以下のようにします。

import re
# 特定の単語を含む文を抽出
pattern = r'Python'
text = "Pythonは楽しい。Pythonは人気のあるプログラミング言語です。"
matches = re.findall(pattern, text)
print("マッチした部分:", matches)
マッチした部分: ['Python', 'Python']

日付やメールアドレスの検出に応用する

正規表現は、日付やメールアドレスの検出にも広く使用されます。

以下は、日付とメールアドレスを検出する例です。

import re
# 日付とメールアドレスのパターン
date_pattern = r'\d{4}/\d{1,2}/\d{1,2}'
email_pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
text = "私のメールは example@example.com で、日付は2023/10/05です。"
# 日付を検出
dates = re.findall(date_pattern, text)
# メールアドレスを検出
emails = re.findall(email_pattern, text)
print("検出した日付:", dates)
print("検出したメールアドレス:", emails)
検出した日付: ['2023/10/05']
検出したメールアドレス: ['example@example.com']

HTMLタグの抽出に応用する

正規表現を使用してHTMLタグを抽出することも可能です。

ただし、HTMLの構造が複雑な場合、正規表現だけでは不十分なことがありますが、簡単なケースでは有効です。

import re
# HTMLタグを抽出するパターン
pattern = r'<(.*?)>'
html_text = "<div>こんにちは</div><p>これはテストです。</p>"
# タグを抽出
tags = re.findall(pattern, html_text)
print("抽出したHTMLタグ:", tags)
抽出したHTMLタグ: ['div', '/div', 'p', '/p']

パターンの一部を変数として動的に変更する

正規表現パターンの一部を変数として動的に変更することで、柔軟な検索が可能になります。

以下はその例です。

import re
# 検索する単語を変数として指定
search_word = "Python"
pattern = rf'\b{search_word}\b'
text = "Python is fun. Python is a popular programming language."
# 動的に生成したパターンを使用
matches = re.findall(pattern, text)
print("マッチした部分:", matches)
マッチした部分: ['Python', 'Python']

このように、正規表現を使って複雑なパターンを変数に格納し、さまざまな応用が可能です。

これにより、特定のニーズに応じた柔軟な検索が実現できます。

よくある質問

r(raw string)を使わないとどうなる?

r(raw string)を使わない場合、バックスラッシュ\がエスケープシーケンスとして解釈されるため、正規表現のパターンが意図した通りに動作しないことがあります。

例えば、\dは数字を表しますが、通常の文字列では\dがエスケープシーケンスとして解釈され、正しくマッチしない可能性があります。

  • pattern = '\\d+'(通常の文字列)では、\dがエスケープされ、意図した動作をしない。
  • pattern = r'\d+'(raw string)では、正しく数字にマッチする。

変数に格納したパターンが動作しない原因は?

変数に格納した正規表現パターンが動作しない原因はいくつか考えられます。

主な原因は以下の通りです。

  • エスケープの不足:特定の文字(例:.*など)を正規表現で使用する際に、エスケープが必要な場合があります。
  • パターンの誤り:正規表現の構文が間違っていると、期待したマッチが得られません。
  • データの形式:検索対象のデータが正規表現パターンに合致していない場合、マッチしないことがあります。

これらの点を確認することで、問題を特定しやすくなります。

re.compile()を使うべきタイミングは?

re.compile()を使うべきタイミングは以下のような場合です。

  • 同じパターンを複数回使用する場合:同じ正規表現パターンを何度も使用する場合、re.compile()を使ってパターンをコンパイルすることで、パフォーマンスが向上します。
  • 可読性を向上させたい場合:複雑な正規表現を使用する際、re.compile()を使うことで、コードがすっきりし、可読性が向上します。
  • パターンにフラグを設定したい場合re.compile()を使用すると、フラグ(例:re.IGNORECASE)を指定して、パターンの動作を変更することができます。

これらの状況において、re.compile()を使用することが推奨されます。

まとめ

この記事では、Pythonにおける正規表現のパターンを変数に格納して使用する方法や、動的にパターンを生成するテクニック、さらに複雑なパターンを再利用する方法について詳しく解説しました。

正規表現を効果的に活用することで、データの検索や抽出がより効率的に行えるようになります。

ぜひ、実際のプロジェクトや日常のプログラミングにおいて、これらのテクニックを試してみてください。

  • URLをコピーしました!
目次から探す