正規表現(regex)の使い方:開発者のための完全ガイド
正規表現をゼロから学びます。基本構文、文字クラス、量指定子、グループ、lookahead、lookbehind、そしてメール・電話番号・URL・IP向けの代表的なパターンを実例付きで解説します。
正規表現とは何か、何に使うのか
正規表現(regex / regexp)は、文字列の検索・検証・置換を高い精度で行うためのパターンです。プログラミング、運用、ログ解析、データ処理で非常に重要な道具です。
正規表現は、言い換えると検索ルールを文字で表したものです。条件分岐を何十行も書く代わりに、1つのパターンで複雑な判定を表現できます。
よくある用途:
- 入力検証: メール、電話番号、URL、郵便番号などの形式チェック
- 検索と置換: 長い文章やコードから特定パターンを見つけて一括変換
- 情報抽出: ログや非構造テキストから必要な値を抜き出す
- ログ解析: エラー、IP、ステータスコード、ルートの分析
- Lint / 整形: コード規約や命名規則の確認
- Web ルーティング: URL パターンの定義
Regex は JavaScript、Python、Java、C#、PHP、Ruby、Go、Rust などほぼすべての主要言語で利用できます。grep、sed、awk のような CLI ツールでも使われます。
読みながら試したいなら、別タブで Regex テスター を開いてください。
基本構文:リテラル文字とメタ文字
正規表現の構文は、大きく分けてリテラル文字とメタ文字から成ります。
リテラル文字: 文字や数字、多くの記号はそのまま一致対象になります。たとえば cat は文字列中の "cat" を探します。
基本メタ文字:
| メタ文字 | 意味 | 例 | 一致例 |
|---|---|---|---|
. | 改行以外の任意の1文字 | c.t | "cat", "cot", "c3t" |
^ | 行頭 / 文字列先頭 | ^Hello | 先頭の "Hello" |
$ | 行末 / 文字列末尾 | world$ | 末尾の "world" |
* | 0回以上 | ab*c | "ac", "abc", "abbc" |
+ | 1回以上 | ab+c | "abc", "abbc" |
? | 0回または1回 | colou?r | "color", "colour" |
| | OR 条件 | cat|dog | "cat" または "dog" |
\ | エスケープ | \. | 文字としてのドット |
メタ文字を文字として検索したい場合は \ でエスケープします。たとえば \.、\*、\\ です。
実用例: "price: $9.99" を探すなら price: \$9\.99 のように書きます。
文字クラスと定義済みクラス
文字クラスは、ある位置に許可される文字集合を表します。
| パターン | 意味 | 一致例 |
|---|---|---|
[abc] | a, b, c のいずれか | "a", "b", "c" |
[a-z] | 任意の小文字 | "a", "m", "z" |
[A-Z] | 任意の大文字 | "A", "M", "Z" |
[0-9] | 任意の数字 | "0", "5", "9" |
[a-zA-Z0-9] | 英数字 | "a", "3", "Z" |
[^0-9] | 数字以外 | "a", "!", " " |
定義済みクラス: \d は数字、\w は単語構成文字、\s は空白です。大文字の \D、\W、\S はそれぞれ否定版です。
単語境界: \bcat\b は単語としての "cat" に一致し、"cater" には一致しません。
実用例: 英数字とハイフンのみを許可するなら ^[a-zA-Z0-9-]+$ が便利です。
量指定子と繰り返しの制御
量指定子は、直前の要素が何回出現してよいかを指定します。
| 量指定子 | 意味 | 例 | 一致例 |
|---|---|---|---|
* | 0回以上 | \d* | "", "5", "123" |
+ | 1回以上 | \d+ | "5", "123" |
? | 0回または1回 | -?\d+ | "42", "-42" |
{n} | ちょうど n 回 | \d{4} | "2026" |
{n,} | n 回以上 | \d{2,} | "12", "123" |
{n,m} | n〜m 回 | \d{2,4} | "12", "1234" |
量指定子は通常 greedy で、できるだけ多くを取ろうとします。後ろに ? を付けると lazy になり、必要最小限だけ取ります。
たとえば <b>Hello</b> and <b>World</b> に対して、<b>.*</b> は全体を取り、<b>.*?</b> は各タグを個別に取ります。
実用例: ^\d{5}(-\d{4})?$ は米国 ZIP コードの5桁または拡張付き形式を検証できます。
キャプチャグループと参照
グループを使うと、パターンをまとまりとして扱い、一致した部分を後で再利用できます。
| 構文 | 種類 | 説明 |
|---|---|---|
(pattern) | キャプチャグループ | 一致内容を保存する |
(?:pattern) | 非キャプチャグループ | グループ化のみ行う |
(?<name>pattern) | 名前付きグループ | 名前を付けて保存する |
\1, \2 | 後方参照 | 前のグループ内容を再利用する |
例: (\d{4})-(\d{2})-(\d{2}) は ISO 日付から年・月・日を取り出します。
名前付きグループ (?<year>\d{4}) のように書くと、コード側で扱いやすくなります。
後方参照は重複単語や対応する引用符の検出に便利です。たとえば (\w+)\s+\1 や (['"])(.*?)\1 です。
代替条件: (https?|ftp):// は "http://", "https://", "ftp://" のいずれかに一致します。これらは Regex テスター で確認できます。
Lookahead と Lookbehind:位置のアサーション
Lookahead と Lookbehind は、現在位置の前後に特定パターンがあるかを確認しますが、文字自体は消費しません。
| 構文 | 名前 | 意味 |
|---|---|---|
(?=pattern) | Positive lookahead | 後ろにそのパターンが必要 |
(?!pattern) | Negative lookahead | 後ろにそのパターンがあってはいけない |
(?<=pattern) | Positive lookbehind | 前にそのパターンが必要 |
(?<!pattern) | Negative lookbehind | 前にそのパターンがあってはいけない |
例1: ^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{8,}$ は強いパスワードを検証します。
例2: (?<=\$)\d+\.\d{2} はドル記号を除いた価格を抽出します。
例3: \w+(?!\s*:) は後ろにコロンがない単語を探します。
例4: (?<!-)\b\d+\b は正の数だけを拾います。Regex エンジンによっては Lookbehind の制約が異なります。
よく使うパターン:メール、電話番号、URL、IP
以下は実務でよく使われる代表的なパターンです。特にメールのような複雑な形式では、サーバー側検証も併用してください。
1. メール: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
2. 国際電話番号(E.164): ^\+?[1-9]\d{1,14}$
3. URL: ^https?:\/\/[\w.-]+(?:\.[a-zA-Z]{2,})(?:\/[\w.~:/?#\[\]@!$&'()*+,;=-]*)?$
4. IPv4: ^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$
5. ISO 日付: ^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$
6. CSS の16進カラー: ^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$
これらのパターンは Regex テスター で調整でき、JSON 全体の検証には JSON バリデーター も使えます。
フラグ、性能、ベストプラクティス
Regex を実務で安全に使うには、フラグと性能・保守性の基本を理解しておく必要があります。
| フラグ | 名前 | 効果 |
|---|---|---|
g | Global | すべての一致を取得 |
i | Case insensitive | 大文字小文字を無視 |
m | Multiline | ^ と $ を行単位で解釈 |
s | Dotall | ドットが改行にも一致 |
u | Unicode | Unicode を正しく扱う |
JavaScript では /pattern/flags、Python では re.compile(r'pattern', re.IGNORECASE | re.MULTILINE) のように使います。
- 壊滅的バックトラッキングを避ける:
(a+)+$のような曖昧なパターンは高コストです - 具体的に書く:
.+より[a-z]+のほうが安全な場面が多いです - アンカーを使う:
^と$で探索範囲を絞れます - 不要なキャプチャを避ける:
(?:...)を活用します - 繰り返し使うパターンはコンパイルする: 実行コストを下げられます
複雑な Regex はコメント化し、正例・負例の両方でテストしてください。また、HTML・XML・JSON を深く解析する用途には専用パーサーを使うべきです。練習には Regex テスター を使えます。
このツールを試す:
ツールを開く→よくある質問
Regex の * と + と ? の違いは何ですか?
アスタリスク(*)は 0 回以上、プラス(+)は 1 回以上、疑問符(?)は 0 回または 1 回を意味します。つまり ? は直前の要素を任意にします。
正規表現でメールアドレスを検証するには?
実用的なパターンとしては ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ があります。一般的な形式はカバーできますが、本番ではサーバー側の確認も必要です。
\d \w \s は何を意味しますか?
\d は数字、\w は単語構成文字、\s は空白文字です。大文字の \D、\W、\S はそれぞれ否定形になります。
Lookahead は何のために使いますか?
Lookahead は文字を消費せずに、現在位置の後ろに特定パターンがあるかを確認する仕組みです。強いパスワードの検証などで非常に便利です。
壊滅的バックトラッキングとは何ですか?
曖昧なパターンのせいで Regex エンジンが膨大な組み合わせを試す状態です。より具体的なパターンを書く、入れ子の量指定子を避ける、厳密な構造を使うことで防げます。
Regex はどの言語でも同じように動きますか?
完全には同じではありません。基本は似ていますが、Lookbehind、Unicode、エスケープ、再帰などの高度な機能には言語ごとの差があります。