あちこちググって、正規表現を色々と無造作にひっかけてきてみました。
で、大まかな検証結果と、前提になる「mailの規約関連」。
http://saboten009.blogspot.jp/2008/02/php_25.html
1. メールアドレスは local part と domain が @ で区切られて構成されている。(RFC2822)
2. local partは、アルファベット、数字、以下の記号 ! # $ % & ' * + - / = ? ^ _ ` { | } ~ で、ドット「 . 」で区切られている場合がある。ただし、最初、最後、他のドットの隣にあってはいけない。(つまり連続しないことということか) (RFC2822 3.2.4)
3. local partは、 クオーテーションマーク「 " 」のなかにスペースを含むいろんな文字が入った quoted string を含むことがある (RFC2822 3.2.5)
4. \@ などの "quoted pair" をlocal partに含むものも「正しい」が "obsolete" (RFC822、RFC2822 4.4) (RFC2822はRFC822をsupersedeしてobsoleteにした、とある)
5. local partの最大長は 64文字 (RFC2821 4.5.3.1)
6. domainは、labelがドットで区切られたものである (RFC1035 2.3.1)
7. domainは、アルファベットで始まり、その後に、0文字以上のアルファベット、数字、ハイフン「 - 」が続き、最後の一字はアルファベットか数字。(RFC1035 2.3.1)
8. labelの最大長は 63字 (RFC1035 2.3.1)
9. domainの最大長は 255字 (RFC2821 4.5.3.1)
10. domainは、fully qualifiedで、DNSのtype AもしくはMXレコードでresolvableでなければならない (RFC2821 3.6)
大まかに。
1番は「これを外してるのは見たことがない」ので、よいと思う。
2番が結構色々と悲喜交々で、「どの記号がいけるのか」の実装依存が強い感じ。
3番の対応は「必要だと思う」んだけど、あんまり見た記憶がないかも(苦笑
4番はそもそもobsoleteなので、あんまり気にしない。
5番はまぁ「必要ならチェックしてくれ」って感じだ。
6〜10までは正確には「ドメインの記法」だと思う…んだが、ここでも結構色々と、ある。
細かいコードは後述するとして。
大まかに…まず「メアドで各処理をチェック」してくと。
@がない
これを外す表現はさすがにないw
local-part先頭の.(ドット)はNG
割とあちこち外してる…「意図的」な可能性があるやつや、スイッチ次第で「是とも非とも」ってのもあるんだけど。
言っちゃなんだが、phpspotさんがOKなのは少しだけ意外w
local-part最後の.(ドット)はNG
「先頭dot」と微妙に結果が違うのがとても面白いw
domain-part先頭の.(ドット)はNG
これコケる実装系があるのが不思議。
でも「コケる実装」書いてあるBlogがあるんだよ?
domain-partの最後はアルファベットまたは数字のみ
これコケる実装系があるのが不思議。ちなみにこれは「最後にアンダースコアいれた」ケース。
symfony_1さんがコケてるのが大変に意外。なんかあるのかなぁ?
domain-partの最後はアルファベットまたは数字のみ(その2)
これは「最後にdot」のケース。…ある意味正しいんだけどねぇwww
これもいくつかの実装系でコケてます。
domain-partのアンダースコアはNG
これは、厳密には少し議論が出そうなテストなんだけど。
細かい話はこちらを。
http://ya.maya.st/d/200605c.html#s20060529_2
ただまぁ「事故りそうな可能性も多々」なので、どっちかってぇと「弾く前提」のほうがいいような気がせんでもない。
nobody@example.com(普通のアドレス)
エラーが出る処理系があるこの不思議感w
0nobody@example.com (先頭を数字に)
これも謎エラーがいくつか発生。
!nobody@example.com (先頭を記号に)
エラーが増えるねぇ…
nobody@1st.example.com (ドメイン名の先頭を数字に(昔は駄目だった))
微妙な所だけど、いくつかがinvalidにしてきた。
Abc\@def@example.com (quoted pair(ただしこれはobsolete))
これは一通りエラー。まぁ順当な気もする。
!#$%&'*+-/=?^_`.{|}~@example.com (使用可能な記号の群れ)
"da.me.."@example.com (これは「quoted string」なのでvalidなパターンその1)
この辺もガチ勢の健闘が目立ちますw
"nobody@nobody"@example.com (これは「quoted string」なのでvalidなパターンその2)
大体一緒。symfony_2がNGなのが微妙に目立つかな。
nobody-regexp@gmail.com (いわゆる拡張アドレスその2)
一方でこっちは「NGがほとんど無い」あたりも、違う意味で気になります。
ideaさんが「どっちもNG」なので、ある意味あり。でもdocomoとかの携帯のアドレスって普通にハイフン入ってなかったっけ?
"nobody-regexp"@gmail.com (いわゆる拡張アドレスその4(拡張+quoted))
いっしょ。
で、次に「処理系単位で」意図に反する動作をする子を見ていると…
unガチ勢は、割とinvalidを通す一方でvalidを通さない、っていうある意味わかりやすい状況が色々とつまびらかに。
ガチ勢は「invalidは大体はねる」「validが通らないことが稀に(でもまぁ歴史的状況的経緯もあるしなぁ…な子が通らないくらい)」。
php_filter意外が、quoted string系通さないのが、意外なのか順当なのか。
まぁかように「unガチ勢ほど拡張アドレスをNGにしやすい」ので。
もちろん「ちゃんと分かった上で丁寧に書いている」所もあろうかとは思うんだけど……割と定期的に「駄目な正規表現コードを拝見したり」、あまつさえ「プログラムなんてググってコピペすればいいんだよ」とかいう話を見たり聞いたりすると、色々ともにょったりするわけなのです。
blogからコピペしてもいいけど、コードの読み込みと検証はちゃんとやろうね!!