手軽屋
ツール一覧

メールアドレス正規表現の落とし穴と現実解

公開: 2026-06-16

「メアドのバリデーションを正規表現1本で済ませたい」——よくある要求ですが、RFC 5322に完全準拠した正規表現は約500字の超複雑な式になり、実務では誰も使いません。本記事では実装者が押さえるべき三段階の現実解を整理します。

先に結論

なぜRFC 5322完全準拠は使えないのか

RFC 5322(インターネットメッセージフォーマット)が定めるメールアドレスは、引用文字列・コメント・ドメインリテラルなどを含み、文法的には極めて複雑です。正規表現で完全に表現しようとすると、よく知られた『Mail::RFC822::Address』正規表現は3,000文字を超えます。

実用上、そんな複雑な式を入れても弾けるアドレスはほぼ存在しません。しかも、複雑すぎてレビューもデバッグも不可能で、性能上のリスク(バックトラック爆発によるReDoS)まで増えます。費用対効果が全く合いません。

HTML5 input type="email" の判定

HTML仕様書では <input type="email"> の有効値を、独自の正規表現で定義しています(MDNでも同じ式が紹介されています)。要点は:

つまりHTML5のtype="email"は、すでに「実用的にちょうどよい簡略版」になっています。自分で書く必要はほぼなく、まずはこれを使うのが第一選択肢です。

サーバー側で書く簡易正規表現の現実解

バックエンドでもう一段だけ簡易判定したいときは、以下くらいで十分です。

// ローカル部1文字以上+@+ドット入りドメイン
/^[\w.+-]+@[\w-]+(\.[\w-]+)+$/

// すこし厳しめ:ドメインラベル末尾ハイフン禁止
/^[\w.+-]+@([\w-]*[\w]\.)+[\w-]*[\w]$/

これでも『a@b.c』のような短すぎるものは通ってしまいますが、無効なアドレスがそのままDBに入って後段で例外になるリスクを大きく減らせます。本サイトの 正規表現チェッカー に貼り付けて挙動を確かめてみてください。

本当の到達可能性は『実送信』でしか確認できない

形式が正しくても、宛先が存在するとは限りません。typo@gmaill.com、退会したアドレス、企業の引退ドメイン、迷惑メールフィルタで弾かれる構成——これらは正規表現では一切判定できません。

そのため、次のような二段構えが定石です。

  1. フォーマットの簡易チェック:HTML5の input type="email" またはサーバー側の簡易正規表現。
  2. 確認メール送信+本人によるクリック:ダブルオプトイン。これで初めて『生きているアドレス』と判定。

ダブルオプトインまで実装する余裕がない管理画面なら、せめて『退会・無効化のリンクを目立つ場所に置く』『同じドメインへの大量送信エラー時にアラートを出す』など運用カバーが必要です。

ReDoS(正規表現サービス停止攻撃)に注意

複雑なメール正規表現には、バックトラックが爆発して数秒〜数分CPUを占有する『ReDoS脆弱性』が見つかることがあります。Web入力欄に直接ぶつかる場合、これは攻撃に使われ得るDoSベクタです。

対策は:①シンプルな正規表現にする、②入力文字数の上限を先に切る(例えば254文字でカット — RFC 5321の最大長)、③RE2系のリニア時間エンジンを使う、です。

補足

正規表現の動作を実際に確かめる

上の簡易メール正規表現を貼って、手元のサンプルでマッチ件数・取り出されるグループを確認できます:正規表現チェッカー