Python re モジュール

Python のreモジュールは、正規表現を処理するための標準ライブラリモジュールです。

正規表現(Regular Expression、略称 regex または regexp)は、テキストのマッチング、検索、操作を行うための強力なツールです。

を通じてreモジュールを使用すると、Python で正規表現を使って文字列を処理できます。

なぜ re モジュールを使うのか?

テキストを処理するとき、特定のパターンを検索したり、文字を置換したりする必要がよくあります。例えば、メールアドレスの検証、Webページ内のリンクの抽出、テキストの整形などです。これらの処理を手作業でコーディングすると非常に面倒な場合がありますが、正規表現はこれらの問題を簡潔かつ効率的に解決する方法を提供します。


re モジュールの基本用法

1. re モジュールをインポートする

使用する前に、reモジュールをインポートする必要があります:

import re

2. よく使う re モジュール関数

2.1 re.match()

re.match()関数は、文字列の先頭位置から正規表現にマッチします。マッチが成功した場合はマッチオブジェクトを返し、それ以外の場合はNone。

例

import re

pattern = r"hello"
text = "hello world"

match = re.match(pattern, text)
if match:
    print("マッチ成功:", match.group())
else:
    print("マッチ失敗")

出力:

匹配成功: hello

2.2 re.search()

re.search()関数は、文字列内で正規表現の最初のマッチを検索します。re.match()とは異なり、re.search()文字列の先頭位置からマッチを開始する必要はありません。

例

import re

pattern = r"world"
text = "hello world"

match = re.search(pattern, text)
if match:
    print("マッチ成功:", match.group())
else:
    print("マッチ失敗")

出力:

匹配成功: world

2.3 re.findall()

re.findall()関数は、文字列内で正規表現にマッチするすべての部分文字列を検索し、リストを返します。

例

import re

pattern = r"\d+"
text = "There are 3 apples and 5 oranges."

matches = re.findall(pattern, text)
print("見つかった数字:", matches)

出力:

找到的数字: ['3', '5']

2.4 re.sub()

re.sub()関数は、文字列内で正規表現にマッチする部分を置換します。

例

import re

pattern = r"apple"
text = "I have an apple."

new_text = re.sub(pattern, "banana", text)
print("置換後のテキスト:", new_text)

出力:

替换后的文本: I have an banana.

正規表現の基本構文

1. 通常の文字

通常の文字(英字、数字など)は、そのまま自身にマッチします。

例

import re

pattern = r"cat"
text = "The cat is on the mat."

match = re.search(pattern, text)
if match:
    print("マッチ成功:", match.group())

出力:

匹配成功: cat

2. 特殊文字

正規表現には、特別な意味を持つ特殊文字がいくつかあります。例:

  • .:任意の1文字(改行以外)にマッチします。
  • *:直前の文字に0回以上マッチします。
  • +:直前の文字に1回以上マッチします。
  • ?:直前の文字に0回または1回マッチします。
  • \d:任意の数字文字にマッチします([0-9])。
  • \w:任意の英字、数字、またはアンダースコア文字にマッチします([a-zA-Z0-9_])。

例

import re

pattern = r"\d+"
text = "The price is 100 dollars."

match = re.search(pattern, text)
if match:
    print("マッチ成功:", match.group())

出力:

匹配成功: 100

3. 文字セット

文字セットは、文字グループ内の任意の1文字にマッチするために使います。例えば、[abc]マッチしますa、b 或 c。

例

import re

pattern = r"[aeiou]"
text = "Hello World!"

matches = re.findall(pattern, text)
print("見つかった母音:", matches)

出力:

找到的元音字母: ['e', 'o', 'o']

4. グループ化

グループ化により、複数の文字をまとめて操作できます。例えば、(abc)マッチしますabc。

例

import re

pattern = r"(ab)+"
text = "ababab"

match = re.search(pattern, text)
if match:
    print("マッチ成功:", match.group())

出力:

匹配成功: ababab

実践演習

練習1:メールアドレスの検証

メールアドレスの形式を検証する正規表現を記述します。

例

import re

pattern = r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"
email = "[email protected]"

if re.match(pattern, email):
    print("有効なメールアドレス")
else:
    print("無効なメールアドレス")

練習2:電話番号の抽出

テキストから電話番号を抽出する正規表現を記述します。

例

import re

pattern = r"\d{3}-\d{3}-\d{4}"
text = "My phone number is 123-456-7890."

match = re.search(pattern, text)
if match:
    print("見つかった電話番号:", match.group())

1. コア関数

メソッド 説明 例
re.compile(pattern) 正規表現を事前コンパイル(再利用性能の向上) pat = re.compile(r'\d+')
re.search(pattern, string) 文字列内で最初のマッチを検索 re.search(r'\d+', 'a1b2')→ マッチ'1'
re.match(pattern, string) 文字列の先頭位置からマッチ re.match(r'\d+', '123a')→ マッチ'123'
re.fullmatch(pattern, string) 文字列全体の完全マッチ re.fullmatch(r'\d+', '123')→ マッチ'123'
re.findall(pattern, string) 重複しないすべてのマッチのリストを返す re.findall(r'\d+', 'a1b22c') → ['1', '22']
re.finditer(pattern, string) すべてのマッチのイテレータを返す(位置情報を含む) for m in re.finditer(r'\d+', 'a1b2'): print(m.group())
re.sub(pattern, repl, string) マッチした部分を置換 re.sub(r'\d+', 'X', 'a1b2') → 'aXbX'
re.split(pattern, string) マッチした部分で文字列を分割 re.split(r'\d+', 'a1b2c') → ['a', 'b', 'c']
re.escape() 特殊文字をエスケープ re.escape("C:\\Users\\test.txt")
re.purge() キャッシュをクリア re.purge()

2. マッチオブジェクト(Match)のメソッド/プロパティ

メソッド/プロパティ 説明 例
group() マッチした文字列全体を返す m.group() → 'abc'
group(n) n番目のキャプチャグループの内容を返す m = re.search(r'(\d)(\d)', '12'); m.group(1) → '1'
groups() すべてのキャプチャグループのタプルを返す m.groups() → ('1', '2')
start()/end() マッチの開始/終了位置 m.start() → 0
span() マッチ範囲を返す(start, end) m.span() → (0, 2)

3. 正規表現メタ文字(一部)

メタ文字 説明 マッチ例
. 任意の文字にマッチ(改行を除く) a.c → 'abc'
\d 数字にマッチ \d+ → '123'
\D 非数字にマッチ \D+ → 'abc'
\w 単語文字(英数字、アンダースコア)にマッチ \w+ → 'Ab_1'
\W 非単語文字にマッチ \W+ → '!@#'
\s 空白文字(スペース、タブなど)にマッチ \s+ → ' \t'
\S 非空白文字にマッチ \S+ → 'abc'
[] 文字集合 [A-Za-z]→ 任意の英字
^ 文字列の先頭にマッチ ^\d+→ 先頭の数字
$ 文字列の末尾にマッチ \d+$→ 末尾の数字
* 直前の文字に0回以上マッチ a* → '', 'aaa'
+ 直前の文字に1回以上マッチ a+ → 'a', 'aaa'
? 直前の文字に0回または1回マッチ a? → '', 'a'
{m,n} 直前の文字にm回以上n回以下マッチ a{2,3} → 'aa', 'aaa'
| または(OR)操作 cat|dog → 'cat' 或 'dog'
() キャプチャグループ (\d+)→ 数字を抽出

4. コンパイルフラグ(flagsパラメータ)

フラグ 説明 例
re.IGNORECASE (re.I) 大文字と小文字を区別しない re.search(r'abc', 'ABC', re.I)
re.MULTILINE (re.M) マルチラインモード(影響^と$) re.findall(r'^\d+', '1\n2', re.M) → ['1', '2']
re.DOTALL (re.S) 让 .改行文字を含むすべての文字にマッチ re.search(r'a.*b', 'a\nb', re.S)
re.ASCII 让 \w, \WなどはASCII文字のみにマッチ re.search(r'\w+', 'こん', re.ASCII)→ マッチなし
re.VERBOSE (re.X) 正規表現内のコメントと空白を許可 re.compile(r'''\d+ # 匹配数字''', re.X)

例

1. メールアドレスの抽出

例

import re

text = "Contact: [email protected], [email protected]"
emails = re.findall(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', text)
print(emails)  # 出力: ['[email protected]', '[email protected]']

2. 日付形式の置換

例

date_str = "Today is 05-15-2023"
new_str = re.sub(r'(\d{2})-(\d{2})-(\d{4})', r'\3年\1月\2日', date_str)
print(new_str)  # 出力: "Today is 2023年05月15日"

3. 複数条件のマッチ

例

pattern = re.compile(r'''
    ^(?P<username>\w+) # ユーザー名
    :(?P<password>\S+) # パスワード
    @(?P<domain>\w+\.\w+) # ドメイン
$'''
, re.VERBOSE)

m = pattern.match("john:[email protected]")
if m:
    print(m.groupdict())  # 出力: {'username': 'john', 'password': 'pass123', 'domain': 'example.com'}

4. 複雑な文字列の分割

例

text = "Apple1Banana2Cherry3Date"
parts = re.split(r'\d+', text)
print(parts)  # 出力: ['Apple', 'Banana', 'Cherry', 'Date']

注意事項

  1. raw 文字列:正規表現では raw 文字列(r'\d')の使用をお勧めします。エスケープ文字の競合を避けるためです。

  2. 貪欲マッチ:デフォルトは貪欲マッチです(例:.*は可能な限り最長の文字列にマッチします)。非貪欲マッチを実現するには.*?を使用します。

  3. パフォーマンス最適化:頻繁に使用される正規表現は優先的にre.compile()プリコンパイルする。

  4. バックトラッキング問題:複雑な正規表現はパフォーマンスの問題を引き起こす可能性がある(例:入れ子になった量指定子(a+)+)。

その他の拡張