正規表現(Regular Expression、略してregex)は、文字列のパターンを記述するための強力なツールです。プログラミング、データ処理、テキスト編集など幅広い場面で活用できます。この記事では、初心者から中級者までを対象に、基本構文から実践的なテクニックまでを解説します。
📖 基本のメタ文字
正規表現では、特別な意味を持つ「メタ文字」を使ってパターンを表現します。まずはよく使う基本的なメタ文字を見てみましょう。
| メタ文字 | 意味 | 例 |
|---|---|---|
. | 任意の1文字(改行以外) | a.c → abc, aXc |
^ | 行の先頭 | ^Hello → 行頭のHello |
$ | 行の末尾 | end$ → 行末のend |
\d | 数字(0-9) | \d{3} → 123, 456 |
\w | 英数字とアンダースコア | \w+ → hello, test_1 |
\s | 空白文字 | a\sb → a b |
🔄 量指定子(繰り返し)
パターンの繰り返し回数を指定するのが量指定子です。データのバリデーションや抽出に欠かせません。
| 構文 | 意味 | 例 |
|---|---|---|
* | 0回以上 | ab*c → ac, abc, abbc |
+ | 1回以上 | ab+c → abc, abbc |
? | 0回または1回 | colou?r → color, colour |
{n} | ちょうどn回 | \d{4} → 2026 |
{n,m} | n回以上m回以下 | \d{2,4} → 12, 123, 1234 |
💡 ヒント:デフォルトは「貪欲」マッチ(できるだけ長く一致)です。
?を付けると「非貪欲」(最短一致)になります。例:.*?🎯 文字クラス
角括弧 [] を使って、マッチさせたい文字の集合を定義できます。
| 構文 | 意味 | 例 |
|---|---|---|
[abc] | a, b, cのいずれか | [aeiou] → 母音 |
[^abc] | a, b, c以外 | [^0-9] → 数字以外 |
[a-z] | 範囲指定 | [A-Za-z] → 英字 |
[\u3040-\u309F] | ユニコード範囲 | ひらがなにマッチ |
🔗 グループと選択
丸括弧 () でグループ化し、| で選択肢を表現できます。キャプチャグループは後方参照や置換にも活用できます。
(\d{4})-(\d{2})-(\d{2})→ 日付の年・月・日を個別にキャプチャ
(?:jpg|png|gif|webp)→ 非キャプチャグループで画像拡張子にマッチ
🚀 実践パターン集
実際の開発でよく使う正規表現パターンを紹介します。そのままコピペして使えます。
メールアドレス
[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}基本的なメール形式の検証に使えます
電話番号(日本)
0\d{1,4}-\d{1,4}-\d{4}固定電話・携帯電話の形式に対応
日付(YYYY-MM-DD)
\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])ISO 8601形式の日付を検証
郵便番号
\d{3}-\d{4}日本の郵便番号形式(123-4567)
🔍 先読み・後読み(Lookahead / Lookbehind)
マッチ結果に含めずに条件を指定できる高度なテクニックです。
| 構文 | 名前 | 説明 |
|---|---|---|
(?=...) | 肯定先読み | 直後に...が続く位置にマッチ |
(?!...) | 否定先読み | 直後に...が続かない位置 |
(?<=...) | 肯定後読み | 直前に...がある位置にマッチ |
(?<!...) | 否定後読み | 直前に...がない位置 |
\d+(?=円)→ 「100円」の「100」だけにマッチ(「円」は含まない)
💻 言語別の使い方
JavaScript
const email = "test@example.com";
const pattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
console.log(pattern.test(email)); // true
// 置換例
const text = "2026-04-02";
const result = text.replace(/(\d{4})-(\d{2})-(\d{2})/, "$1年$2月$3日");
// "2026年04月02日"Python
import re
text = "郵便番号: 123-4567, 987-6543"
result = re.findall(r"\d{3}-\d{4}", text)
print(result) # ['123-4567', '987-6543']
# 名前付きグループ
m = re.search(r"(?P<year>\d{4})-(?P<month>\d{2})", "2026-04")
print(m.group("year")) # 2026🏆 正規表現をマスターするコツは、小さなパターンから始めて少しずつ複雑にしていくこと。オンラインツール(regex101.comなど)で試しながら学ぶのが効果的です。
❓ よくある質問
正規表現とワイルドカードの違いは?
ワイルドカード(*や?)はファイル検索などで使う簡易的なパターンです。正規表現はより複雑なパターンを記述でき、キャプチャや先読みなどの高度な機能も備えています。
正規表現のパフォーマンスは大丈夫?
簡単なパターンなら問題ありません。ただし、複雑なバックトラックが発生するパターン(例:(a+)+)は避けましょう。「ReDoS」攻撃の原因になります。
おすすめの学習方法は?
まずこの記事の基本を押さえ、regex101.comなどのオンラインツールで実際に試してみましょう。少しずつ複雑なパターンに挑戦するのが上達のコツです。