- 2009/3/20 金曜日 1:00:13
- perl
(タイトルはid:hasegawayosukeさんが言ってたよ)
ああ、まただよ…
「PHP使いはもう正規表現をblogに書くな」と言わせないでくれ
正規表現って、プログラミング言語間の差が少ないサブ言語なのに、なぜ「DAN」がつくとダメ正規表現ばかり登場するのか。うんざりだ。
飽きたので以下略。
簡潔に。(正規表現はdanさんのものからシングルクォートコンテキストにあわせてエスケープをしてあります)
<?php $email = 'test@example.com' . "\n"; $re = '/^(?:(?:(?:(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+)(?:\.(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+))*)|(?:"(?:\\\\[^\r\n]|[^\\\\"])*")))\@(?:(?:(?:(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+)(?:\.(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+))*)|(?:\[(?:\\\\\S|[\x21-\x5a\x5e-\x7e])*\])))$/'; if (preg_match($re,$email)) { echo "valid"; } else { echo "invalid"; } ?>
これの結果が「valid」になる。当然rfc5322でdot-atomには改行は(CRであれLFであれ)許されていない。
対策はdanさん自身が^$でなくて\A\zを使おうで述べているとおり。
<?php $email = 'test@example.com' . "\n"; $re = '/\A(?:(?:(?:(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+)(?:\.(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+))*)|(?:"(?:\\\\[^\r\n]|[^\\\\"])*")))\@(?:(?:(?:(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+)(?:\.(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+))*)|(?:\[(?:\\\\\S|[\x21-\x5a\x5e-\x7e])*\])))\z/'; if (preg_match($re,$email)) { echo "valid"; } else { echo "invalid"; } ?>
ただしjavascriptではmフラグをつけない限りは$は改行直前にはマッチしないので問題なかったりもする。
ところでこの正規表現には他にも問題が残っている。domain-literalで\\\Sにマッチするようになっているがこれはなんなのだろう。
<?php $email = 'test@[127.0.0.1' . "\\\x1f]"; $re = '/\A(?:(?:(?:(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+)(?:\.(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+))*)|(?:"(?:\\\\[^\r\n]|[^\\\\"])*")))\@(?:(?:(?:(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+)(?:\.(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+))*)|(?:\[(?:\\\\\S|[\x21-\x5a\x5e-\x7e])*\])))\z/'; if (preg_match($re,$email)) { echo "valid"; } else { echo "invalid"; } ?>
おかげで上記のコードもvalidだ。なんてこった。domain-literalなんてそもそもはずしてもいいような気もするけど、対応するとしたらこれでいんじゃないだろうか。
<?php $email = 'test@[127.0.0.1' . "\\\x1f]"; $re = '/\A(?:(?:(?:(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+)(?:\.(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+))*)|(?:"(?:\\\\[^\r\n]|[^\\\\"])*")))\@(?:(?:(?:(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+)(?:\.(?:[a-zA-Z0-9_!#\$\%&\'*+\/=?\^`{}~|\-]+))*)|(?:\[[\x21-\x5a\x5e-\x7e]*\])))\z/'; if (preg_match($re,$email)) { echo "valid"; } else { echo "invalid"; } ?>
\\\Sになんか意味があるんだったらすみません。知ってる人いたら教えてください。
追記1(2009/03/20 01:57): コード例の(html)エスケープがおかしかったのを直しました。
追記2(2009/03/20 05:36): \\\Sに関してdanさんより404 Blog Not Found:regexp – ‘test@[127.0.0.1’ . "\\\x1f]" はRFC2822準拠で説明いただきました。ちなみにRFC5322にはquoted-pairはないかとおもってたら、obs-dtextの中にしっかり生き残ってた…。
コメント:0
トラックバック:2
- この記事のトラックバック URL
- https://blog.everqueue.com/chiba/2009/03/20/151/trackback/
- トラックバックの送信元リスト
- 「danコガいはもう正規表現をblogに書くな」と言わせないでくれ - へぼい日記 より
- trackback - 404 Blog Not Found より 2009/3/20 金曜日
regexp – ‘test@[127.0.0.1’ . “\\\x1f]” はRFC2822準拠
私自身驚いたのだが、’test@[127.0.0.1′ . “\\\x1f]”はRFC2822準拠でなのである。
へぼへぼCTO日記 – 「danコガいはもう正規表現をblogに書くな」と言わせないでくれおかげで上記のコードもvalidだ。…- pingback - 正規表現によるメールアドレスチェックの正解がわからないので、自己責任で。 | doli blog より 2014/3/2 日曜日
[…] 「danコガいはもう正規表現をblogに書くな」と言わせないでくれ | へぼい日記 […]