Python | 正規表現(re)

Python
スポンサーリンク

正規表現(re モジュール)はテキスト処理で超便利ですが、最初は記号の意味に慣れることが肝心です。ここでは 初心者が最短で使えるように、概念→主要パターン→re の使い方→実例→練習問題(解答付き)まで、やさしくまとめます。コードはそのまま Python で動きます。

1. 正規表現って何?

正規表現(regex)は「文字列パターンを表す式」です。メールや電話番号の抽出、ログ解析、置換などで使います。短くて強力ですが、最初は少し記号を覚えるだけでかなり使えるようになります。


2. 基本の考え方(重要)

  • 正規表現は「検索したい文字列のルール」を書いたもの。
  • Python では import re して、re.search() / re.match() / re.findall() / re.sub() などを使います。
  • パターンは 生文字列(raw string)で書くのがおすすめ:r"..."。バックスラッシュの扱いが楽になります。
import re
pat = r"\d+"   # 数字が1回以上
re.findall(pat, "abc123def45")  # -> ['123','45']
Python

3. よく使う記号(覚え方メモ)

文字系

  • .:任意の1文字(改行は除く、フラグで変える)
  • \d:数字(0-9) — 同義 [0-9]
  • \D:数字以外(\d の否定)
  • \w:単語構成文字(英数字+アンダースコア) — 同義 [A-Za-z0-9_]
  • \W\w 以外
  • \s:空白(スペース、タブ、改行など)
  • \S:空白以外

量指定(回数)

  • a*:0 回以上(可能な限り多く)
  • a+:1 回以上(最もよく使う)
  • a?:0 回または 1 回(あるかも)
  • a{m}:ちょうど m 回
  • a{m,n}:m〜n 回(範囲)

位置とグループ

  • ^:行頭(例:^Hello
  • $:行末(例:end$
  • ():グループ化・キャプチャ(後で参照)
  • (?: ):グループ化するがキャプチャしない(性能向上や後方参照不要時に便利)
  • |:または(OR)

例(分かりやすさ重視)

  • ^\d{4}-\d{2}-\d{2}$YYYY-MM-DD 形式にマッチ(行全体が日付と一致)
  • \bword\b → 単語単位で word にマッチ(単語境界 \b

4. Python の re でよく使う関数

import re

re.search(pattern, text)     # パターンが anywhere にあるか。Matchオブジェクト or None
re.match(pattern, text)      # 文字列先頭からマッチするか(search と違う)
re.findall(pattern, text)    # マッチする全ての部分文字列をリストで返す
re.finditer(pattern, text)   # マッチのイテレータ(Matchオブジェクトを順に)
re.sub(pattern, repl, text)  # 置換(repl は文字列か関数)
re.split(pattern, text)      # パターンで分割してリストを返す
re.compile(pattern, flags)   # パターンをコンパイル(同じパターンを複数回使うなら有利)
Python

Match オブジェクトからは .group() .groups() .start() .end() が使えます。


5. フラグ(オプション)

  • re.I / re.IGNORECASE:大文字小文字を区別しない
  • re.M / re.MULTILINE^$ が行単位になる
  • re.S / re.DOTALL. が改行にもマッチする
    例:re.search(pattern, text, re.I | re.M)

6. 実用的な例(そのままコピペして試せます)

例 A — 数字列を全部取り出す

import re
text = "商品A: 123円, 商品B: 45円, #ID: 007"
nums = re.findall(r"\d+", text)
print(nums)  # ['123','45','007']
Python

例 B — Eメールっぽいものを抽出(単純版)

text = "連絡は taro@example.com または hanako@sample.co.jp へ"
emails = re.findall(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}", text)
print(emails)
Python

※ 厳密な RFC 準拠ではありませんが、実務的には十分な場合が多いです。

例 C — 電話番号(日本の簡易パターン:例 03-1234-5678 や 090-1234-5678)

text = "連絡先: 03-1234-5678, 携帯: 090-9876-5432"
phones = re.findall(r"\b0\d{1,4}-\d{1,4}-\d{4}\b", text)
print(phones)
Python

例 D — 置換(複数スペースを1つのスペースに)

s = "これは   スペースが   多い  文です"
s2 = re.sub(r"\s+", " ", s).strip()
print(s2)  # "これは スペースが 多い 文です"
Python

例 E — グループを使って抽出(年月日のパーツ)

m = re.search(r"(\d{4})-(\d{2})-(\d{2})", "今日は2025-11-05です")
if m:
    year, month, day = m.groups()
    print(year, month, day)  # '2025' '11' '05'
Python

7. よくある「間違い」と対処法

  • バックスラッシュを忘れる → "\d" と書くと Python 側で解釈されることがある。r"\d" を使おう。
  • re.match() は「先頭」からしか見ない → 文字列内どこでも探したいときは re.search() を使う。
  • 貪欲(greedy)と非貪欲(lazy):.* はできるだけ長くマッチする。最小マッチにしたいときは .*? を使う。
    例:"<.+>"<a> <b><a> <b> 全体にマッチするが、"<.+?>" は最短の <a><b> に分かれる。
  • 日本語や Unicode を扱うときも \w などは英数字中心なので注意。必要なら文字クラス [\u3040-\u30FF\u4E00-\u9FFF] のように指定する(やや上級)。

8. 練習問題 — 解答付き

問1:文字列 "abc123xyz456" から数字だけを取り出してリストにしなさい。

解答:

import re
s = "abc123xyz456"
re.findall(r"\d+", s)  # -> ['123', '456']
Python

問2:"price: .5, tax: .25" から小数も含めた金額を抜き出す正規表現を書きなさい。

解答:

import re
s = "price: $12.5, tax: $1.25"
re.findall(r"\$\d+(?:\.\d+)?", s)  # -> ['$12.5', '$1.25']
Python

問3:行頭に # がある行をコメント行として省いたリストを作りたい(テキストは改行で複数行)。どうする?

解答:

import re
text = "line1\n# comment\nline2\n#x\nline3"
lines = text.splitlines()
non_comments = [ln for ln in lines if not re.match(r"^\s*#", ln)]
# -> ['line1','line2','line3']
Python

問4(少し応用):HTML の簡単なタグ <tag>...</tag> の中身だけ取り出す。ただしネストや属性は無視してOK。

解答:

import re
html = "<p>Hello</p><div>World</div>"
re.findall(r"<([a-zA-Z][a-zA-Z0-9]*)>(.*?)</\1>", html)
# -> [('p','Hello'), ('div','World')]
# グループ1はタグ名、グループ2は中身
Python

9. まとめ(実務での使い分け)

  • 単純な文字列検索や分割→ split, str.replace, in で十分。
  • パターンが複雑(形式チェック、抽出、複数条件)→ 正規表現が強力。
  • 大きなテキストや頻繁に同じパターンを使うなら re.compile() でパターンをコンパイルして使うと速くてコードが読みやすい。
Python
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました