もんりぃ is undefined.

育児ネタとか、技術ネタとか。

JavaScript の正規表現では \A や \z が使えない。

前置き

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');
}

一言

んー、この辺のルールは身体で覚えるしか無いのかしら…。

処理系によって解釈が変わるから、色々と混乱するですよ(´•ω•`)