メアドのバリデーションチェック

非常に面倒なメアドのバリデーションチェック。PHPだと「filter_var()」でチェック可能

作成日:2018-02-15, 更新日:2018-10-04

ルール

RFCの規定において有効なメールアドレス「ローカル部@ドメイン(例:hoge@example.com)」の場合。

・メールアドレス全体の長さの最大値は254文字
・ローカル部は64文字、ドメインの長さの最大値は253文字
・携帯電話のメールアドレスなど例外あり

「ローカル部」で使って良い文字:基本ルール

・大小のラテン文字、数字
・「! # $ % & ' * + - / = ? ^ _ ` { | } ~」(実際には、プロバイダ側で利用可能な記号文字を一部のみに制限している場合が多い)
・「.」(先頭と末尾以外で使用可能。2個以上連続してはならない)

「""」で囲む場合

・「.」(先頭と末尾で使用可能。2個以上連続してもOK)
・「( ) < > [ ] : ; @ ,」
・スペース

「""」で囲んだ上で「\」を追加する

・「\」を使うとき「\\」
・「"」を使うとき「\"」

「ドメイン」で使って良い文字:基本ルール

・ラテン文字、数字(先頭はラテン文字または数字)
・「-」
・ラテン文字・数字・“-”から成るサブドメインを「.」でつないだ形式

IPアドレスで指定

・「[]」で囲んだIPアドレス([192.168.0.100])

存在するドメイン、IPかチェック

そこまでする必要は無いかなぁ・・・。必要があるときは「checkdnsrr()」があるっぽい。

参照:PHP ドメインの有効性チェック(checkdnsrr())

PHPでバリデーション(書式チェック)

$email = 〇〇〇;
if ( !filter_var($email, FILTER_VALIDATE_EMAIL)) {
   // エラー
}

※「FILTER_VALIDATE_EMAIL」は「PHP:検証フィルタ」を参照。

「"」で囲んでも空白を含むとエラーになった。
たぶん他にもあると思うし・・・サーバの設定等で変わってくると思う。

追加のバリデーションチェック

メアドのバリデーションチェックは問題ないけど、エラーにしたい内容。

大概の記号は「"」で囲めばバリデーションチェックでOKとなる。
→「"」を含むのは認めない

if ( strpos($email, '"') === false ) {
  if ( !filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // エラー
  }
}
else {
  // エラー
}

Javascriptでバリデーション(書式チェック)

日本語が通るから完璧じゃないけど、ひとまず使えるっぽい。

function isEmail(email){
   return /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$/.test( email );
}

var email = 〇〇〇;
if ( !isEmail(email) ) {
   // エラー
}

rfc822 email validation in JS

メールアドレスのバリデーション

バリデーションが通るからと言って「OK」としたくないコトもある。

例えば・・・「@」前を「"」で囲まれたメアドはバリデーションで通るけど、そのメアドをログインIDにした場合はどうする?
メアドでログインしてもらうとき時に毎回、「@」前を「"」で囲んでもらう?
それとも、プログラムで追加させる?
・・・諸々考えると面倒なので、避けたい。

ということで、ひとまず下記ルール。
・「@」が一つある。
・「@」前は「.」で始まらない
・「@」前は「.」で終わらない
・「@」前は「.」が連続していない
・「@」前は「英数」と「.」と「! # $ % & ' * + - / = ? ^ _ ` { | } ~」のみ
・「@」後は「- .」と「英数」のみ。
・「@」後は「- .」で始まらない
・「@」後は「- .」で終わらない
・「@」後は「.」が連続していない
・「"」は使えない
・「スペース」は使えない
※「@」前を「"」で囲んでもダメ
※「@」後のIPアドレスはダメ

ドメインルールが微妙・・・下記のような感じになっている。
・「-example.com」「example.com-」はNG
・「example-.com」「example.-com」はOK

function isEmailSimple(email){
   // 「\w」「! # $ % & ' * + - / = ? ^ _ ` { | } ~」:「\w」は「英数(A-Za-z0-9)」
   var base = '\\w!#$%&' + "'" + '*+\\-/=?\\^_`{|}~';
   
   // 「@」の前:「英数記号」で始まり、「英数記号」と「.」があり、「英数記号」で終わる。
   // ※「@」の前は1文字でもOKらしい・・・。
   // var before = '[' + base + '][' + base + '\\.]+[' + base + ']'; // 2018/03/28にコメント
   
   // ▼2018/03/28に追加
   var elm = email.split('@');
   if ( elm.length!=2 || elm[0]=='' ) {
     return false;
   }
   
   var before = '';
   if ( 3 < elm[0].length ) {
     before = '[' + base + '][' + base + '\\.]+[' + base + ']';
   }
   else {
     before = '[' + base + ']+';
   }
   // ▲2018/03/28に追加
   
   // 「@」の後:「英数」で始まり、「英数」と「. - 」があり、「英数」で終わる。
   var after  = '[\\w][\\w\\.\\-]+[\\w]';
   
   //// 日本語ドメインやIPアドレスも対応させる場合:たぶんコレでOKなハズ。
   //var tmpDomain = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x5b([^\\x0d\\x5b-\\x5d\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x5d';
   //var after = '(' + tmpDomain + ')\\x2e(' + tmpDomain + ')*';
   
   var mailFormat = '^' + before + '\\@' + after + '$';
   
   var re = new RegExp(mailFormat);
   
   var result = re.test(email);
   if ( result ) {
      // 連続した「.」があるか確認
      result = !( /\.{2,}/.test(email) );
   }
   
   return result;
}

関連項目

PHP ドメインの有効性チェック(checkdnsrr())
メールアドレスのバリデーションチェック(PHPとJavascript)のサンプル