PHPでメールアドレスとURLのチェックに正規表現を使うな
へー、って思ったので実際に調べてみた
EMAILをチェックするときの書き方
正しければ、値がそのまま返り、間違っていればfalseが返ります
var_dump(filter_var('[email protected]', FILTER_VALIDATE_EMAIL));
// string(15) "[email protected]"
var_dump(filter_var('ば[email protected]', FILTER_VALIDATE_EMAIL));
// bool(false)
RF2822準拠しているメールアドレスをチェックしている?
懐かしいですが、404 Blog Not Found:「PHP使いはもう正規表現をblogに書くな」と言わせないでくれから例をいただきます
var_dump(filter_var('[email protected]', FILTER_VALIDATE_EMAIL));
// bool(false)
var_dump(filter_var('[email protected]', FILTER_VALIDATE_EMAIL));
// string(25) "[email protected]"
docomoの残念なアドレスを相手にする必要がある企業のサイトなんかだと使えないかもしれないですね
速度比較
filter_varと正規表現を100回実行したときの速度を比較してみる
$start_m = microtime();
$start = time();
for ($i=0; $i < 100; $i++){
filter_var('[email protected]', FILTER_VALIDATE_EMAIL);
}
$end_m = microtime();
$end = time();
$bench = ($end - $start) + ($end_m - $start_m);
var_dump($bench);
// float(0.001258)
$reg = '
/^(?:(?:(?:(?:[a-zA-Z0-9_!#\$\%&\'*+/=?\^`{}~|\-]+)(?:\.(?:[a-zA-Z0-9_!#\$\%&\'*+/=?\^`{}~|\-]+))*)|(?:"(?:\\[^\r\n]|[^\\"])*")))\@(?:(
';
$start_m = microtime();
$start = time();
for ($i=0; $i < 100; $i++){
preg_match($regexp, '[email protected]');
}
$end_m = microtime();
$end = time();
$bench = ($end - $start) + ($end_m - $start_m);
var_dump($bench);
// float(6.59288)~~~
<del datetime="2012-04-13T10:50:07+00:00">速度は圧倒的にfilter_varが早いですね。</del>
正規表現が間違えてました!
PHPでwarningが出ていた為に遅かったようです
$regexp = ‘/^(?:[^(\040)<>@,;:”.\\[]\000-\037\x80-\xff]+(?![^(\040)<>@,;:”.\\[]\000-\037\x80-\xff])|”[^\\\x80-\xff\n\015″]*(?
$start_m = microtime();
$start = time();
for ($i=0; $i < 100; $i++){
preg_match($regexp, ‘[email protected]’);
}
$end_m = microtime();
$end = time();
$bench = ($end – $start) + ($end_m – $start_m);
var_dump($bench);
// float(0.000362)
~~~
正規表現が動かない件はここにも書いてありました
小飼弾様、正規表現の件、やってみたけどできません | Others | ウェビンブログ
というわけで
この結果でいい人は使うといいと思います
受託だとそれぞれ変なルールがあって難しい気が \(^o^)/
速度はほぼ同じ&正規表現ならルールも案件にあわせて変更可能ということで、filter_varの出番はなさそうですね
コメント
preg_match版の変数名がおかしい($regに代入して$regexpを使ってる)のと、1回のマッチに65ミリ秒も掛かるのがちょっと信じがたかったので自分でも試してみました。
正規表現はfilter_varで使ってるのと同じものにしてあります。
https://gist.github.com/2375573
1万回実行しても差がほとんど見られない感じになりました。
おそらくpreg_match版のほうに何かのバグがあり、毎回E_WARNINGかなんかが出てたんではないかと思います。
まさにその通りで変数名が間違ってました
ついでに正規表現自体も間違っていますね
遅すぎて変だなーと気づくべきでした