【Python】正規表現のフラグ活用:複数行モードとDOTALLモードの完全ガイド

Pythonの re モジュールで、改行を含むテキストデータを扱う際に必須となるのが「フラグ」の指定です。特に、行単位でのマッチングを行いたい場合の re.MULTILINE と、改行をまたいでマッチングを行いたい場合の re.DOTALL は、挙動を正しく理解していないと意図した結果が得られません。

この記事では、チャットログや複雑なテキストデータを例に、これらのフラグが特殊文字(^, $, .)に与える影響と、その使い分けを解説します。

目次

特殊文字とフラグの対応表

特殊文字デフォルトの挙動re.MULTILINE (複数行)re.DOTALL (改行一致)
. (ドット)改行以外の1文字にマッチ変化なし改行を含む全ての文字にマッチ
^ (キャレット)文字列全体の先頭のみ各行の行頭変化なし
$ (ドル)文字列全体の末尾のみ各行の行末変化なし

実装例:チャットログの解析

ユーザーからのメッセージが複数行にわたる場合があるチャットログを想定し、特定のパターンを抽出します。

シナリオ

以下のような形式のログから、2つの異なる抽出を行います。

  1. 各メッセージのヘッダー行(ユーザー名と日時)だけを取得したい。
  2. ヘッダーからメッセージ本文を含めた1つの発言ブロック全体を取得したい。

ソースコード

import re

# 解析対象:チャットアプリのログデータ
# ユーザー名とタイムスタンプの行があり、その後にメッセージが続く(複数行の場合あり)
chat_log = """[UserA] 10:00
Hello everyone.
Check this out.

[UserB] 10:05
Good morning!
I will check it later.

[UserC] 10:10
Thanks."""

# パターンA: 行頭の [User...] を含む行だけを抽出
# ^ : 行頭、.+ : 1文字以上
pattern_line = r"^\[User.*\].+$"

# パターンB: [User...] から次の空行(または末尾)までのブロック全体を抽出
# ^ : 行頭、.+? : 最短マッチ、$ : 行末(ブロックの終わり)
pattern_block = r"^\[User.*?\].+?$"

print("--- 1. re.MULTILINE のみ使用 ---")
# ^ と $ を「各行」の先頭・末尾にマッチさせる
# 結果: ヘッダー行だけが抽出される(メッセージ本文は無視される)
headers = re.findall(pattern_line, chat_log, flags=re.MULTILINE)
for h in headers:
    print(f"Header found: {h}")

print("\n--- 2. re.MULTILINE | re.DOTALL の併用 ---")
# MULTILINE : ^ を各ブロックの開始位置にマッチさせる
# DOTALL    : . を改行にもマッチさせ、複数行のメッセージを含める
# 結果: 各ユーザーの発言ブロック全体が抽出される
blocks = re.findall(pattern_block, chat_log, flags=re.MULTILINE | re.DOTALL)

for i, block in enumerate(blocks, 1):
    print(f"--- Block {i} ---\n{block}")

実行結果

--- 1. re.MULTILINE のみ使用 ---
Header found: [UserA] 10:00
Header found: [UserB] 10:05
Header found: [UserC] 10:10

--- 2. re.MULTILINE | re.DOTALL の併用 ---
--- Block 1 ---
[UserA] 10:00
Hello everyone.
Check this out.
--- Block 2 ---
[UserB] 10:05
Good morning!
I will check it later.
--- Block 3 ---
[UserC] 10:10
Thanks.

解説

1. 各行を個別に処理する (re.MULTILINE)

デフォルトでは ^ は文字列全体の先頭([UserA]の前)にしかマッチしません。re.MULTILINE を指定することで、^ が「各行の始まり」を意味するようになり、途中の [UserB][UserC] の行頭も検出できるようになります。ログの見出し行だけをリスト化したい場合に有効です。

2. 改行を含む範囲をまとめる (re.DOTALL)

メッセージ本文に改行が含まれている場合、通常の . は改行で止まってしまいます。re.DOTALL を指定することで、. が改行文字(\n)も飲み込むようになり、複数行にわたるテキストブロックを一括でキャプチャできます。

この2つのフラグは、flags=re.MULTILINE | re.DOTALL のようにビット演算子 | を使って同時に指定することが可能です。これにより、「行頭から始まり、複数行にわたる内容を含んでマッチする」という柔軟な検索が実現できます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次