Pythonの正規表現(reモジュール)を世界一わかりやすく解説!初心者向けに基本から実用例まで
「大量のテキストデータから、メールアドレスだけを全部抜き出したい」「ログファイルに特定のキーワードを含む行だけを抽出したい」
このような定型的な文字列操作は、ビジネスシーンで頻繁に発生します。一つひとつ手作業でコピー&ペーストするのは大変な手間ですよね。そんなとき、プログラミングの世界には「正規表現(せいきひょうげん)」という、文字列の達人がいます。
この記事では、Pythonを使って正規表現を扱う方法を、専門家でないビジネスパーソンのあなたにも分かるように、ゼロから丁寧に解説します。この記事を読み終える頃には、面倒な文字列処理を自動化する第一歩を踏み出せているはずです。
正規表現とは? なぜ便利なの?
正規表現とは、一言で言えば「特定のパターンを持つ文字列を表現するためのルール」です。英語では “Regular Expression” と呼ばれ、しばしば “Regex” と略されます。
例えば、「3桁の数字 – 4桁の数字」というパターンを持つ郵便番号や、「〇〇@△△.com」というパターンを持つメールアドレスなどを、特定の記号の組み合わせで表現できます。
この「ルール」を使うことで、コンピュータに以下のような指示を出すことが可能になります。
- 文章中から、このパターンに一致する文字列をすべて探して(検索)
- 見つけ出した文字列だけを抜き出して(抽出)
- パターンに一致する文字列を、別の文字列に置き換える(置換)
Pythonでは、この正規表現を扱うための「re」という標準機能(専門的には「モジュール」と呼びます)が用意されており、誰でもすぐに利用を始めることができます。
Pythonの「reモジュール」- 文字列操作の万能ナイフ
Pythonで正規表現を使うには、まずプログラムの冒頭で `import re` と書くだけで準備完了です。これにより、reモジュールという便利な道具箱が使えるようになります。ここでは、その中でも特によく使われる代表的な道具(関数)を4つ紹介します。
| 関数 | 主な役割 | 簡単な説明 |
|---|---|---|
re.search() |
検索(最初の一つを見つける) | 文字列全体を調べて、パターンに最初に一致した箇所を見つけます。見つかればその情報(マッチオブジェクト)を、見つからなければ何も返しません。 |
re.match() |
検索(先頭が一致するか調べる) | 文字列の先頭からパターンに一致するかを調べます。文字列の途中にあるパターンは無視されます。 |
re.findall() |
抽出(一致する全てを見つける) | パターンに一致する部分を全て探し出し、リスト(複数のデータを格納できる箱)の形で返します。最もよく使う関数の一つです。 |
re.sub() |
置換(見つけて置き換える) | パターンに一致する部分を、指定した別の文字列に置き換えます。文書のフォーマット整形などで大活躍します。 |
初心者のうちは、「文字列のどこかにあるパターンを探したいなら re.search()」、「パターンに合うものを全部抜き出したいなら re.findall()」と覚えておくと良いでしょう。
正規表現の基本文法 – パターンを組み立てるための記号たち
正規表現のパターンは、通常の文字(a, b, c, 1, 2, 3など)と、特別な意味を持つ「メタ文字」を組み合わせて作ります。ここでは、絶対に覚えておきたい基本的なメタ文字を紹介します。

| メタ文字 | 意味 | 具体例 |
|---|---|---|
. |
改行以外の任意の1文字 | a.c は “abc”, “a_c”, “a3c” などに一致します。 |
* |
直前の要素の0回以上の繰り返し | ca*t は “ct”, “cat”, “caaat” などに一致します。 |
+ |
直前の要素の1回以上の繰り返し | ca+t は “cat”, “caaat” には一致しますが、”ct” には一致しません。 |
? |
直前の要素の0回または1回の出現 | colou?r は “color” と “colour” の両方に一致します。 |
\d |
任意の数字([0-9] と同じ) | \d\d\d は “123”, “987” などの3桁の数字に一致します。 |
\w |
任意の英数字またはアンダースコア([a-zA-Z0-9_] と同じ) | \w+ は “hello”, “user_01” など単語に一致します。 |
\s |
任意の空白文字(スペース、タブ、改行など) | hello\sworld は “hello world” に一致します。 |
[] |
角括弧内のいずれか1文字 | [abc] は “a”, “b”, “c” のいずれか1文字に一致します。[0-9]で全ての数字を表せます。 |
() |
パターンをグループ化する | 後で特定の部分だけを取り出すのに使います。(cat)+ は “cat” や “catcat” に一致します。 |
パターン構築の思考法:分解して組み立てる
正規表現のパターンを組み立てるコツは、「探したい文字列の特徴を、言葉で分解してみる」ことです。例えば、「日本の携帯電話番号(例: 090-1234-5678)」を探したい場合、以下のように分解できます。
- 「0」で始まる
- 次に数字が2つ続く
- 「-」(ハイフン)がある
- 次に数字が4つ続く
- 「-」(ハイフン)がある
- 最後に数字が4つ続く
これを先ほどのメタ文字で表現に変換していくと、0\d{2}-\d{4}-\d{4} のようなパターンが完成します。({n} は直前の要素がn回繰り返すことを意味します)
import re
text = "連絡先は090-1234-5678です。予備は080-8765-4321になります。"
# 携帯電話番号のパターン
pattern = r"0\d{2}-\d{4}-\d{4}"
phone_numbers = re.findall(pattern, text)
print(phone_numbers)
# 出力結果: ['090-1234-5678', '080-8765-4321']
ポイント: パターン文字列の前に r を付ける(例: r"...")と、「raw文字列」となり、バックスラッシュ \ をPythonが特別な意味を持つ文字として解釈しなくなるため、正規表現のパターンを記述する際は、この書き方が推奨されます。
実務で役立つ正規表現の具体例
それでは、実際の業務でどのように正規表現が役立つか、いくつかのシナリオを見ていきましょう。

1. メールアドレスを全て抽出する
顧客リストや問い合わせメールの本文から、メールアドレスだけを抜き出したいケースです。
import re
document = """
山田太郎さんのアドレスは taro.yamada@example.com です。
お問い合わせは、公式サポート support-info@company.co.jp までお願いします。
無効なアドレス: user@localhost
"""
# メールアドレスを抽出するパターン
# [英数字._%-が1回以上]@[英数字.-が1回以上].[英字が2文字以上]
email_pattern = r"[\w.%+-]+@[\w.-]+\.[a-zA-Z]{2,}"
emails = re.findall(email_pattern, document)
print(emails)
# 出力結果: ['taro.yamada@example.com', 'support-info@company.co.jp']
このパターンを使えば、様々な形式のメールアドレスを効率的に収集できます。
2. ログデータから特定の情報を抜き出す(グループ化の活用)
Webサーバーのアクセスログなど、決まったフォーマットのテキストから必要な部分だけを抜き出したい場合、() を使ったグループ化が非常に役立ちます。() で囲んだ部分は、後から個別に参照できます。
例えば、[日付] [レベル] メッセージ という形式のログから、「エラーレベルがERRORの行のメッセージだけ」を抽出してみましょう。
import re
log_data = """
[2025-11-06] INFO サーバーを起動しました。
[2025-11-06] DEBUG ユーザーのリクエストを受信しました。
[2025-11-06] ERROR データベースへの接続に失敗しました。
[2025-11-07] INFO 処理が正常に完了しました。
[2025-11-07] ERROR ファイルが見つかりません。
"""
# エラーメッセージを抽出するパターン
# 行頭が[日付] ERROR (←ここが欲しいメッセージ) というパターン
error_pattern = r"^\[.+?\]\s+ERROR\s+(.+)$"
error_messages = []
for line in log_data.splitlines():
match = re.search(error_pattern, line)
if match:
# グループ(1)にメッセージ部分が格納されている
error_messages.append(match.group(1))
print(error_messages)
# 出力結果: ['データベースへの接続に失敗しました。', 'ファイルが見つかりません。']
この例では、(.+) でメッセージ部分をグループ化し、match.group(1) でその部分だけを取り出しています。これにより、大量のログの中から重要な情報だけを効率的に集計できます。
3. 文書のフォーマットを整形する(置換の活用)
re.sub() を使うと、テキストの整形作業を自動化できます。例えば、文中にある全角の数字を半角に統一したり、不要な空白を削除したりといった処理が得意です。
ここでは、複数の連続する空白やタブを、半角スペース1つに置き換える例を見てみましょう。
import re
raw_text = "この記事は Pythonの 正規表現について\t解説します。"
# \s+ は1回以上の空白文字(スペース、タブなど)に一致
cleaned_text = re.sub(r"\s+", " ", raw_text)
print(cleaned_text)
# 出力結果: "この記事は Pythonの 正規表現について 解説します。"
このように、手作業では面倒な表記の揺れやフォーマットの統一を、一瞬で完了させることができます。
初心者が陥りがちな失敗例と対処法
正規表現は強力なツールですが、独特のルールがあるため、初心者がつまずきやすいポイントもいくつか存在します。ここでは代表的な失敗例とその解決策を紹介します。
match()とsearch()の混同- 失敗例: 文字列の途中にあるはずのパターンが
re.match()で見つからない。 - 原因:
re.match()は文字列の先頭がパターンに一致するかどうかしかチェックしません。 - 対処法: 文字列の任意の位置で検索したい場合は、必ず
re.search()を使いましょう。
- 失敗例: 文字列の途中にあるはずのパターンが
- 特殊文字のエスケープ忘れ
- 失敗例: URLに含まれるドット(.)を検索したいのに、
.と書いたらうまくいかない。 - 原因:
.は「任意の1文字」を意味するメタ文字です。 - 対処法: メタ文字そのものを文字として扱いたい場合は、直前にバックスラッシュ
\を付けてエスケープします(例:\.)。*や+,?なども同様です。
- 失敗例: URLに含まれるドット(.)を検索したいのに、
- 貪欲マッチ(Greedy Match)による意図しない広い範囲のマッチ
- 失敗例: HTMLタグ
<p>text1</p> and <p>text2</p>から<p>text1</p>だけを取りたいのに、<p>.*</p>と書いたら全体がマッチしてしまった。 - 原因:
*や+はデフォルトで「貪欲(Greedy)」に振る舞い、可能な限り最も長い文字列にマッチしようとします。 - 対処法: 量指定子の後ろに
?を付けると「非貪欲(Non-Greedy)」になり、最も短い文字列にマッチするようになります(例:.*?)。HTMLやXMLの解析では、この非貪欲マッチが必須テクニックです。
- 失敗例: HTMLタグ
まとめ
この記事では、Pythonの正規表現(reモジュール)について、その基本から実用的な使い方までを解説しました。最初は奇妙な記号の羅列に見えるかもしれませんが、一つひとつの意味を理解し、パターンを分解して組み立てる練習をすれば、必ず使いこなせるようになります。
正規表現をマスターすれば、これまで手作業で何時間もかかっていた文字列処理の作業を、わずか数行のコードで自動化できるようになります。これは、日々の業務効率を劇的に改善する強力なスキルです。
まずは簡単なパターンの作成から挑戦し、徐々に複雑な処理にも応用してみてください。正規表現は、あなたのビジネスにおけるデータ活用能力を、一段上のレベルへと引き上げてくれるはずです。