正規表現によるメールアドレスチェックの正解がわからないので、自己責任で。

正規表現でメールアドレスをバリデート。
前から一度ちゃんと調べてみようとは思っていたんですが、少し調べただけで、いろいろ出てくるから困る。正規表現もいまだ勉強中の身としては、判断が付かない。
実際、厳密にチェックしようと思ったらかなりの困難(無理?)が伴うようで。今まで自分が使っていた正規表現がいい加減なものであることだけはわかりました。では何を使えばいいのやら…。

↓例えば以下のページなどを読ませていただいていると、情報リテラシーが如何に必要で大切かがわかります。どんな情報も鵜呑みにせずに自己責任の上で活用しないとですね。

404 Blog Not Found:「PHP使いはもう正規表現をblogに書くな」と言わせないでくれ

「danコガいはもう正規表現をblogに書くな」と言わせないでくれ | へぼい日記

そもそもメールアドレスについてきちんと調べたことがなかったので、以下を参照。

メールアドレス – Wikipedia

いや~、これまで漠然と「使ってはいけない」と思っていた文字などが普通に使えちゃったりするんですね。ただ、こうも複雑な正規表現をつくろうとすると、私個人のスキルではどうにもならない気もします。これだけ多くの方々が情報提供しあっているのに「これが決定版!」というものに行きつかず、もはや無限ループの如し…。
でも現実問題としてバリデートする必要がある(バリデートしたい)ので、先人のお知恵を拝借せざるを得ません。

ちなみに、以下の文字みんな使用可能(@より前のローカル部だけですが)。

! # $ % & ' * + - / = ? ^ _ ` { | } ~

おおっと、これ全部OKですか。不勉強ですみません。
さらにさらに、「”」で括られた形式(quoted-string)ならば、以下の文字も使えるとは知らなかった。

( ) < > [ ] : ; @ ,

従いまして、以下のアドレスはRFCの規定において有効なメールアドレスになるようです。

RFCの規定において有効なメールアドレス

!#$%&’*+-/=?^_`.{|}~@example.com
“Abc@def”@example.com
“Fred\ Bloggs”@example.com
“Joe.\\Blow”@example.com

っていうか、「”」で括れることが知らなかった…。「@」が使えるって…、衝撃。
さらに電子メールでの使用形式として、以下のような使い方もできるわけで…。

電子メールでの使用が有効な形式

<foo@example.com>
foo <foo@example.com>

そもそも@より後ろのドメイン部などは、IPアドレス形式も使えるとか。

“[ ]”でくくられたIPアドレスもOK

foo@[192.0.2.69]

さらにさらに、2009年以前の携帯キャリアメールなどでは、RFCに準拠していないアドレスも有効だったようで、当時作成されたアドレスは今でも生きているんだとか。

本当はNGだけど有効な携帯キャリアのメールアドレス

foo.@docomo.ne.jp //RFCの基準では@の直前の”.”はNG
foo..foo@docomo.ne.jp //RFCの基準では連続した”.”(ダブルドット)はNG

ああ、これはもうダメだ。私のスキルでは対応できません(笑)。

オーディションの1次書類選考程度と割り切る

ということで、どこかで”妥協の線”を引かねばならないのです。以下、妥協方針を掲げてみました。あくまでの私の場合です。

妥協方針
  1. 厳密なバリデートはあきらめる
  2. 奇をてらったようなアドレスには泣いてもらう(すみません)
  3. IPアドレスは無視(すみません)
  4. 入力フォームに「厳密にはチェックできません」等の注意書きを添える
  5. 皆様からのご指摘には感謝し、お叱りは甘んじて受け入れる
  6. 不適切な記述が発覚したら、都度修正する

目的を見誤らないことが重要かと思います。私の場合、必要なのは正確・厳密にEmailをバリデートすることではなく、大まかなは振るい分けと入力のケアレスミス防止に役立つことです。そこを見失わないこと。0か100かは最初から期待していません。オーディションの書類選考程度の”フィルター“として割り切ることも必要ではないでしょうか。

例えば、メールアドレスにIPアドレスとか使ってお問い合わせやユーザー登録をしてくる人とか、私は要らない…。怖い…。嫌味すぎる…。
記号文字とかたくさん使ったアドレスも、そのせいで今までいろいろな弊害があったと思われるので、弾かれてもあきらめてくれるでしょう。(それでも使い続ける人は、わかった上であえて使用しているのでしょうから)

ひとまず現時点で採用したのは以下です。妥協方針の2番目、3番目が効いていますね。だいぶ簡略化されました。

if ( preg_match('/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/i', $email) ){
     return '正しいメールアドレスです';
} else {
     return '正しくないメールアドレスです';
}

※ 仕事としてクライアントから依頼を受けたなら、妥協点をどこに持っていくのか、クライアントとの相談は必須ですね。

↓こちらの方が作成した関数がよさそうな感じ。(”感じ”しかわからなくてすみません…)

PHPしか書けないザコがメールアドレス正規表現でガチ勢に挑んでみた – Qiita [キータ]

PHP5.2からは filter_var関数も使える

PHP5.2以上では、filter_var関数が使えるようです。

PHP: filter_var – Manual

//メールアドレスチェック
filter_var('myaccount@example.jp', FILTER_VALIDATE_EMAIL);
//URLチェック
filter_var('http://example.jp', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED);

RFC準拠のアドレスをチェックするならばこれでいいんじゃないでしょうか。多少の問題もあるようですけども。

もうこれで行かせて欲しい。

ただfilter_varの場合、docomoなどの昔のキャリアメールではRFCに準拠していないアドレスが有効だったために、チェックに引っかかる場合もあるようです。当時のアドレスをそのまま使っているユーザーもいるでしょうから、全ユーザーに優しいチェックを提供するとなると、filter_var関数は使えないですねえ。面倒な話です。

メールアドレスのRFC準拠について

メールアドレス登録基準(RFC準拠)については以下でわかりやすく解説してくれています。

メールアドレスの登録基準(RFC準拠) | ミニミニ管理者(システム管理者/社内SE/CIO)の独り言

PHP | , , , |