re.match と re.compile(…).match の違い

テクニック

Python で正規表現を使うとき、こんな2通りの書き方があります。

import re

# 方法A: その場で re.match
if re.match(r'^Endpoint:', line):
    ...

# 方法B: 事前に re.compile
RE_END = re.compile(r'^Endpoint:')
if RE_END.match(line):
    ...

見た目は似ていますが、中の仕組みが違うんです。


1. re.match の仕組み

実は re.match(pattern, string)内部で毎回 re.compile(pattern) を呼んでから .match() しています

図にするとこう:

line1 ── re.match("pattern", line1)
          └─ re.compile("pattern")  # ← ここで毎回コンパイル
             └─ .match(line1)

line2 ── re.match("pattern", line2)
          └─ re.compile("pattern")  # ← また新しく作る
             └─ .match(line2)

...

つまり、行を読むたびに「設計図を作って → マッチさせる」ことを繰り返しているイメージです。


2. re.compile(...).match の仕組み

一方で、re.compile を先に呼んでおけば「設計図」は最初の1回だけ。
その後は .match() を繰り返すだけで済みます。

RE = re.compile("pattern")   # 最初に設計図を1回だけ作る

line1 ── RE.match(line1)     # 既に準備済みのパターンを使う
line2 ── RE.match(line2)
line3 ── RE.match(line3)
...

つまり「1回設計 → あとは照合のみ」。大量のテキストを扱うときに高速です。


3. パフォーマンス実験

import re, time

pattern = r'^Endpoint:'
lines = ["Endpoint: U5/D"] * 100_000

# 事前コンパイル
RE = re.compile(pattern)
t0 = time.time()
for ln in lines:
    RE.match(ln)
t1 = time.time()

# 毎回 re.match
t2 = time.time()
for ln in lines:
    re.match(pattern, ln)
t3 = time.time()

print("precompiled:", t1-t0, "sec")
print("re.match   :", t3-t2, "sec")

結果(例):

precompiled: 0.03 sec
re.match   : 0.15 sec

事前コンパイルのほうが数倍速い!


4. まとめ:どちらを使うべき?

  • レポート解析のように何千行も処理するなら
    👉 re.compile で事前に準備して使い回す
  • 学習用スクリプトや一度きりの判定なら
    👉 re.match でもOK(でも癖として re.compile を覚えたほうが良い)

💡 ポイント

  • re.match は「毎回コンパイル」してからマッチ
  • RE = re.compile(...) は「最初だけコンパイル」して後は使い回す
  • 大規模処理では 速度差が大きくなる
  • 名前を付けて変数に入れておくと、コードの可読性・保守性も向上
タイトルとURLをコピーしました