メールアドレスの正規表現|厳密にやるべきでない理由と実用パターン
「メールアドレス 正規表現」で検索すると、数行にわたる複雑なパターンが出てきます。しかし実務でそれを使うべきケースはほとんどありません。 この記事では、なぜ厳密な検証が推奨されないのか、代わりに何をすべきかを整理します。
結論:この程度で十分です
/^[^\s@]+@[^\s@]+\.[^\s@]+$/
意味は「空白でない文字 + @ + 空白でない文字 + . + 空白でない文字」だけです。これ以上厳しくする必要は、通常ありません。
理由は以下で説明します。
理由1:RFC完全準拠の正規表現は実用にならない
メールアドレスの仕様は RFC 5322 で定義されていますが、この仕様は想像以上に寛容です。次のようなアドレスも、仕様上は有効です。
"[email protected]"@example.com
[email protected]
"quoted string"@example.com
RFC に完全準拠した正規表現は数千文字規模になり、可読性も保守性もありません。書けたとしても、レビューできる人がいないコードになります。
そして、そこまでやっても「実在するアドレスか」は分かりません。 [email protected] は形式的に完全に有効ですが、届きません。
理由2:厳しすぎると有効なアドレスを弾く
これが最も実害の大きい問題です。正規表現によるバリデーションの失敗は、「不正なアドレスを通す」より「正しいアドレスを弾く」形で起きます。
日本のキャリアメールの問題
とくに注意が必要なのが、日本の携帯キャリアのメールアドレスです。過去に発行されたアドレスの中には、RFC の仕様に反する形式が含まれています。
[email protected] ← ドットが連続している
[email protected] ← @ の直前にドットがある
これらは RFC 5322 上は不正ですが、実在し、実際に使われています。 仕様に忠実な正規表現を書くと、これらのユーザーが会員登録できません。
「厳密に書いたせいで、一部のユーザーが登録できない」というのは、実際に起きている障害です。 緩いバリデーションで困ることは、ほぼありません。
その他の弾きやすいパターン
| アドレスの形式 | 有効か | 弾かれやすい理由 |
|---|---|---|
[email protected] | 有効 | + を許可していない実装が多い |
[email protected] | 有効 | TLDを2〜4文字に制限すると通るが、下記が通らない |
[email protected] | 有効 | 長いTLDを想定していない |
user@localhost | 環境による | ドットがない(社内システムで使うことがある) |
TLD(.com などの末尾)の文字数を制限してはいけません。 .technology .photography など、長いTLDが多数存在します。よく見かける {2,4} という指定は、現在では誤りです。
理由3:本当の検証は確認メールでしかできない
形式が正しくても、次のケースは検出できません。
- 存在しないアドレス
- タイプミス(
gmial.com、yahooo.co.jp) - 捨てアドレス
- 受信できない状態のアドレス
メールアドレスの唯一の確実な検証方法は、実際にメールを送って確認してもらうことです。
したがって、実務での構成は次の2段階になります。
- 形式チェック — 緩い正規表現で、明らかな入力ミスだけ弾く
- 実在確認 — 確認メールを送り、リンクをクリックしてもらう
正規表現の役割は、1段階目の「ユーザーが @ を入れ忘れた」程度を拾うことに限定されます。ここに労力をかける価値はありません。
実装:HTMLの機能を使う
そもそも自分で正規表現を書かない選択肢もあります。
<input type="email" name="email" required />
type="email" を指定すると、ブラウザが標準のバリデーションを行います。スマートフォンではメールアドレス入力に適したキーボードが表示されるという利点もあり、入力ミス自体が減ります。
ただし、ブラウザのバリデーションは回避可能です。サーバー側でのチェックは別途必要です。
// サーバー側でも同じ緩さでチェックする
const isValidFormat = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
実務で入れるべきチェック
正規表現を厳しくするより、次の処理を入れるほうが効果があります。
1. 前後の空白を除去する
コピー&ペーストで空白が混入するのは非常によくあります。
const email = input.trim();
バリデーションの前に必ず trim() してください。 「正しいのに弾かれる」の原因として最も多いのがこれです。
2. 全角文字を半角に変換する
日本語入力の状態で入力すると、@ や . が全角になります。見た目でほぼ判別できないため、ユーザーは自分のミスに気づけません。
エラーを出すより、自動的に半角へ変換するほうが親切です。 全角半角の変換については全角・半角が混在したデータを一括で揃える方法で詳しく解説しています。
3. 大文字を小文字に正規化する
ドメイン部分は大文字小文字を区別しません。[email protected] と [email protected] は同じドメインです。
重複登録を防ぐには、保存時に小文字へ正規化しておきます(ローカル部の大文字小文字を厳密に区別するメールサーバーも理論上は存在しますが、実務ではまず問題になりません)。
4. よくあるタイプミスを検出する
形式は正しいが、明らかに打ち間違いというケースです。
gmial.com / gmai.com / gmail.co
yahooo.co.jp / yaho.co.jp
これらはエラーにせず、「もしかして gmail.com ですか?」と確認を促すのが適切です。弾いてしまうと、意図的にそのドメインを使っている場合に登録できなくなります。
パターンを検証する
正規表現は、頭の中で動作を追うと必ず間違えます。正規表現テスターツールで、実際の文字列を入れて確認してください。
検証時に必ず試すべき入力は次のとおりです。
通るべきもの
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
弾くべきもの
user@ (ドメインがない)
@example.com (ローカル部がない)
user example.com (@がない)
user@@example.com (@が2つ)
(空文字列)
下の5つが正しく弾かれることを確認してください。 「通るべきものが通る」だけを確認して、「弾くべきものが弾かれるか」を見落とすのがよくある失敗です。
正規表現全般の書き方は正規表現の基本と実務でよく使うパターン集にまとめています。
まとめ
/^[^\s@]+@[^\s@]+\.[^\s@]+$/で十分- RFC完全準拠の正規表現は数千文字になり実用にならない
- 厳しすぎると日本のキャリアメールが弾かれる
- TLDの文字数を制限してはいけない(
{2,4}は誤り) - 実在確認は確認メールでしかできない
- 正規表現を磨くより、trim・全角変換・小文字化を入れるほうが効果的
メールアドレスのバリデーションは、厳しくするほど良くなるものではありません。 目的は「ユーザーの明らかな入力ミスを拾うこと」であって、「仕様を完全に検証すること」ではありません。