Home > perl > 「danコガいはもう正規表現をblogに書くな」と言わせないでくれ

「danコガいはもう正規表現をblogに書くな」と言わせないでくれ

  • 2009-03-20 (金) 1:00
  • perl
  • hatena count

(タイトルは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の中にしっかり生き残ってた…。

Comments:0

Comment Form
Remember personal info

Trackbacks:1

Trackback URL for this entry
http://www.geminium.com/chiba_blog/2009/03/20/151/trackback/
Listed below are links to weblogs that reference
「danコガいはもう正規表現をblogに書くな」と言わせないでくれ from へぼへぼCTO日記
trackback from 404 Blog Not Found 09-03-20 (金) 5:03

regexp – ‘test@[127.0.0.1' . "\\\x1f]” はRFC2822準拠

私自身驚いたのだが、’test@[127.0.0.1' . "\\\x1f]“はRFC2822準拠でなのである。
へぼへぼCTO日記 – 「danコガいはもう正規表現をblogに書くな」と言わせないでくれおかげで上記のコードもvalidだ。…

add to hatena hatena.comment (49) add to del.icio.us (0) add to livedoor.clip (8) add to Yahoo!Bookmark (2) Total: 59

Home > perl > 「danコガいはもう正規表現をblogに書くな」と言わせないでくれ

Search
Feeds
Meta

Return to page top