前置き
JavaScript でメールアドレスのバリデーションを行おうと思って、以下のような正規表現を書いてみた。*1
var value = $('#hoge input[name="email"]').val() || ''; if (value.match(/\A[a-zA-Z0-9_][a-zA-Z0-9.+_-]*@[a-zA-Z0-9._-]+\.[a-zA-Z]{2,}\z/m)) { alert('Valid'); } else { alert('Invalid'); }
んで、いざ処理を通してみると、正しいハズのメールアドレスが通らない。
本題
そもそもの問題点としては、この日記のタイトルの通り。
「いや、それくらい常識でしょ。」って言われたらそれまでなんだけど、\A やら \z やらは ECMAScript な処理系では使えない。
なので、以下のように直してみる。
var value = $('#hoge input[name="email"]').val() || ''; if (value.match(/^[a-zA-Z0-9_][a-zA-Z0-9.+_-]*@[a-zA-Z0-9._-]+\.[a-zA-Z]{2,}$/m)) { alert('Valid'); } else { alert('Invalid'); }
これで、一見問題無いように思える。
けど、以下のように入力文字列に改行が含まれる場合、本来望んでいない値も Valid として判定されてしまう。
monry@hoge.com monry@fuga.com
原因は、パターンの最後に付けてる m 修飾子。これがあると、ダメ。
実は、この正規表現自体は、元々 PHP (preg) で記述した際に用いていたモノで、\A, \z を使うために m 修飾子を入れていて、それを外し忘れたってだけのお話。
結論
正解 *2 は以下の通り。
var value = $('#hoge input[name="email"]').val() || ''; if (value.match(/^[a-zA-Z0-9_][a-zA-Z0-9.+_-]*@[a-zA-Z0-9._-]+\.[a-zA-Z]{2,}$/)) { alert('Valid'); } else { alert('Invalid'); }
一言
んー、この辺のルールは身体で覚えるしか無いのかしら…。
処理系によって解釈が変わるから、色々と混乱するですよ(´•ω•`)