🐍 Python

名前付きグループ:(?P<name>...)

正規表現の丸括弧(...)は「グループ」として一致した部分を取り出せますが、複数のグループがあるとgroup(1)、group(2)のように番号で管理する必要があり、パターンが複雑になるほど「どの番号が何を表すか」が分かりにくくなります。(?P<name>...)という書き方でグループに名前を付けておくと、番号ではなく名前でアクセスできるようになり、AIが生成した正規表現を後から読むときにも意図がすぐ分かります。

構文: (?Pパターン)
アクセス方法: m.group('name') または m.groupdict()

基本の使い方:日付を年・月・日に分解する

それぞれのグループにyear、month、dayという名前を付けています。

import re

m = re.match(r'(?P\d{4})-(?P\d{2})-(?P\d{2})', '2026-08-09')
print(m.group('year'))   # '2026'
print(m.group('month'))  # '08'
print(m.group('day'))    # '09'

groupdict()で辞書としてまとめて取り出す

名前付きグループを1つずつ.group()で呼ぶ代わりに、.groupdict()を使うと全部まとめて辞書として取得できます。設定ファイルのパース結果をそのまま辞書として扱いたいときに便利です。

import re

m = re.match(r'(?P\d{4})-(?P\d{2})-(?P\d{2})', '2026-08-09')
print(m.groupdict())
# {'year': '2026', 'month': '08', 'day': '09'}

名前を付けても番号でもアクセスできる

名前付きグループであっても、通し番号は消えません。.group(1)のような番号アクセスと、.groups()で全グループをタプルとしてまとめて取得する方法も併用できます。

import re

m = re.match(r'(?P\d{4})-(?P\d{2})-(?P\d{2})', '2026-08-09')
print(m.group(1), m.group(2), m.group(3))  # 2026 08 09(名前を付けても番号は生きている)
print(m.groups())                          # ('2026', '08', '09')

省略可能なグループが一致しなかった場合

?を付けて「あってもなくてもよい」グループを作ることができますが、実際に一致しなかった場合、そのグループの値は空文字ではなくNoneになります。この違いを知らずに文字列として扱おうとすると、TypeErrorの原因になります。

import re

m = re.match(r'(\w+)(-(\w+))?', 'foo')
print(m.group(1))  # 'foo'
print(m.group(3))  # None(2つ目のグループは一致しなかったのでNone)
主なメソッド
m.group(name または番号)
指定した名前・番号のグループの値を取得。m.group()やm.group(0)は一致箇所全体
m.groups()
番号付きグループすべてをタプルで取得(名前付きグループも含まれる)
m.groupdict()
名前付きグループだけを辞書として取得
💡 Noneチェックを忘れない

省略可能なグループを含むパターンをAIが生成しているのを見たら、そのグループの値を使う箇所でNoneチェックが行われているかを必ず確認してください。「一致したグループの値を.upper()などの文字列メソッドにそのまま渡している」ようなコードは、そのグループが一致しなかった瞬間にAttributeErrorで落ちる典型的な事故パターンです。

← Python re モジュール リファレンス一覧へ戻る