Pythonの正規表現(reモジュール)とは?

正規表現(regular expression)は、特定の文字列パターンを表現するための強力なツールで、Pythonではreモジュールを使用して実装できます。正規表現を使うことで、文字列の検索、抽出、置換などが非常に効率的に行えます。例えば、メールアドレスの形式を検証したり、特定のパターンに一致するデータを抽出したりすることが可能です。 この記事では、Pythonreモジュールを使った正規表現の基本から応用までを、具体的な例を交えながら解説します。

reモジュールの基本的な使い方

Pythonで正規表現を使うには、まずreモジュールをインポートする必要があります。次に、reモジュールの関数を使って文字列のパターンマッチングを行います。よく使われる関数には、re.search(), re.match(), re.findall(), re.sub()などがあります。

基本的な関数

  • re.search(): 文字列全体の中でパターンに一致する部分を検索します(部分一致)。
  • re.match(): 文字列の先頭がパターンに一致するかどうかを調べます(先頭一致)。
  • re.findall(): 文字列内のすべての一致をリストで返します。
  • re.sub(): パターンに一致する部分を置換します。

例:re.search() を使った検索

import re
text = "`Python`で正規表現を学ぶ"
pattern = "正規表現"
# パターンに一致する部分を検索
result = re.search(pattern, text)
if result:
    print("一致しました:", result.group())  # 出力: 一致しました: 正規表現
else:
    print("一致しませんでした")

この例では、文字列textの中から"正規表現"というパターンを検索しています。re.search()は、一致する部分が見つかった場合にマッチオブジェクトを返し、group()メソッドで一致した部分の文字列を取得できます。

正規表現の基本パターン

正規表現には、さまざまな特殊文字やパターンがあり、これらを組み合わせることで高度な検索や抽出が可能になります。いくつか基本的なパターンを見てみましょう。

任意の1文字(.

.は任意の1文字にマッチします。

import re
text = "cat hat bat"
pattern = ".at"
# 任意の1文字 + "at" にマッチ
result = re.findall(pattern, text)
print(result)  # 出力: ['cat', 'hat', 'bat']

文字クラス([]

[]内に指定した文字のいずれか1文字にマッチします。

import re
text = "cat hat bat"
pattern = "[ch]at"  # "c" または "h" の後に "at" が続くパターン
result = re.findall(pattern, text)
print(result)  # 出力: ['cat', 'hat']

繰り返し(*, +, ?

  • *
    0回以上の繰り返し
  • +
    1回以上の繰り返し
  • ?
    0回または1回の出現
import re
text = "hellooo"
pattern = "o+"
# "o" が1回以上続く部分にマッチ
result = re.findall(pattern, text)
print(result)  # 出力: ['ooo']

アンカー(^, $

  • ^
    文字列の先頭にマッチ
  • $
    文字列の末尾にマッチ
import re
text = "`Python` is fun"
pattern = "^`Python`"  # 先頭が "`Python`" で始まるか確認
result = re.match(pattern, text)
if result:
    print("先頭が一致しました:", result.group())  # 出力: 先頭が一致しました: `Python`

よく使われる正規表現のパターン

数字(\d

\dは任意の数字にマッチします。

import re
text = "2024年の予定"
pattern = "\d+年"  # 数字が1回以上続き、その後に "年" が続くパターン
result = re.search(pattern, text)
print(result.group())  # 出力: 2024年

単語の境界(\b

\bは単語の境界にマッチします。これを使うと、特定の単語のみを検索できます。

import re
text = "cat hat catalog"
pattern = r"\bcat\b"  # "cat" という単語にのみマッチ
result = re.findall(pattern, text)
print(result)  # 出力: ['cat']

OR条件(|

|はOR条件を表し、複数のパターンのいずれかにマッチします。

import re
text = "apple or orange"
pattern = "apple|orange"
result = re.findall(pattern, text)
print(result)  # 出力: ['apple', 'orange']

reモジュールの応用

すべての一致を取得する - re.findall()

re.findall()は、パターンに一致するすべての部分をリストで返します。

import re
text = "メールは test@example.com と info@example.com"
pattern = r"\w+@\w+\.\w+"  # メールアドレスのパターン
result = re.findall(pattern, text)
print(result)  # 出力: ['test@example.com', 'info@example.com']

部分文字列の置換 - re.sub()

re.sub()を使うと、正規表現パターンに一致する部分を置換できます。

import re
text = "2024年は特別な年です"
pattern = "\d+"  # 数字に一致する部分
# 数字を "XXXX" に置換
new_text = re.sub(pattern, "XXXX", text)
print(new_text)  # 出力: XXXX年は特別な年です

正規表現のコンパイル - re.compile()

正規表現を複数 回使用する場合、re.compile()でパターンをコンパイルしておくと効率的です。

import re
# 正規表現をコンパイル
pattern = re.compile(r"\d+")
text = "私は30歳で、兄は25歳です"
# 複数回使用
ages = pattern.findall(text)
print(ages)  # 出力: ['30', '25']

正規表現のフラグ

reモジュールでは、検索時にいくつかのフラグを使って動作をカスタマイズできます。

  • re.IGNORECASE: 大文字と小文字を区別しない
  • re.MULTILINE: 複数行モードで動作(^$が各行の先頭/末尾にマッチ)
  • re.DOTALL: .が改行文字にもマッチするようにする

例:re.IGNORECASE を使った大文字小文字の無視

import re
text = "`Python` is Fun"
pattern = "python"
# 大文字小文字を無視して検索
result = re.search(pattern, text, re.IGNORECASE)
if result:
    print("一致しました:", result.group())  # 出力: 一致しました: `Python`

正規表現の注意点

正規表現は強力ですが、以下の点に注意して使う必要があります。

  1. 過度な複雑化を避ける: 正規表現は複雑になると可読性が低下し、バグを引き起こしやすくなります。必要に応じて適切なコメントを残しましょう。
  2. パフォーマンスに注意: 大規模なデータセットに対して複雑な正規表現を使用すると、パフォーマンスが低下することがあります。

結論

Pythonreモジュールを使った正規表現は、文字列操作において非常に強力なツールです。パターンマッチング、テキストの検索・抽出・置換といった操作が簡単に行え、効率的なテキスト処理が可能です。基本的な構文や関数を理解し、適切に使用することで、日常のプログラム作成やデータ解析の幅が大きく広がります。