gallu’s blog

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

メールアドレスの確認(少し本題:あちこちググってのメアド正規表現の是非)

あちこちググって、正規表現を色々と無造作にひっかけてきてみました。
で、大まかな検証結果と、前提になる「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

連続した.(ドット)はNG

これはとても悩ましいところ(AUDocomoが以下略)。
なので、微妙に言及を避けます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 (使用可能な記号の群れ)

pearsymfony_1、php_filterが優秀だなぁ。

"da.me.."@example.com (これは「quoted string」なのでvalidなパターンその1)

この辺もガチ勢の健闘が目立ちますw

"nobody@nobody"@example.com (これは「quoted string」なのでvalidなパターンその2)

大体一緒。symfony_2がNGなのが微妙に目立つかな。

nobody+regexp@gmail.com (いわゆる拡張アドレスその1)

気になるところ…いわゆる「unガチ勢」が割とこぞってNG出してきやがるのが大変に気にかかります。

nobody-regexp@gmail.com (いわゆる拡張アドレスその2)

一方でこっちは「NGがほとんど無い」あたりも、違う意味で気になります。
ideaさんが「どっちもNG」なので、ある意味あり。でもdocomoとかの携帯のアドレスって普通にハイフン入ってなかったっけ?

"nobody+regexp"@gmail.com (いわゆる拡張アドレスその3(拡張+quoted))

まぁ言わずもがなのガチ勢優勢。

"nobody-regexp"@gmail.com (いわゆる拡張アドレスその4(拡張+quoted))

いっしょ。


で、次に「処理系単位で」意図に反する動作をする子を見ていると…
unガチ勢は、割とinvalidを通す一方でvalidを通さない、っていうある意味わかりやすい状況が色々とつまびらかに。
ガチ勢は「invalidは大体はねる」「validが通らないことが稀に(でもまぁ歴史的状況的経緯もあるしなぁ…な子が通らないくらい)」。
php_filter意外が、quoted string系通さないのが、意外なのか順当なのか。


まぁかように「unガチ勢ほど拡張アドレスをNGにしやすい」ので。
もちろん「ちゃんと分かった上で丁寧に書いている」所もあろうかとは思うんだけど……割と定期的に「駄目な正規表現コードを拝見したり」、あまつさえ「プログラムなんてググってコピペすればいいんだよ」とかいう話を見たり聞いたりすると、色々ともにょったりするわけなのです。


blogからコピペしてもいいけど、コードの読み込みと検証はちゃんとやろうね!!