エクストリームテキストプロセシング
C++0xをdisってる人をdisる闇のC++軍団たち - Togetterに吹いた。
だがちょっと待ってほしい。C++0xは変態過ぎはしないか。たとえば増田からは「正規表現使いたければそれこそ、Perl使え」と主張するような声もある。このような声に闇のC++軍団たちは謙虚に耳を傾けるべきではないか。
傾けてみた。まず、perlfaq9 - Networking - metacpan.orgをコピペして、
#! /usr/bin/perl use strict; my $atom = qr{[a-zA-Z0-9_!#\$\%&'*+/=?\^`{}~|\-]+}; my $dot_atom = qr{$atom(?:\.$atom)*}; my $quoted = qr{"(?:\\[^\r\n]|[^\\"])*"}; my $local = qr{(?:$dot_atom|$quoted)}; my $domain_lit = qr{\[(?:\\\S|[\x21-\x5a\x5e-\x7e])*\]}; my $domain = qr{(?:$dot_atom|$domain_lit)}; my $addr_spec = qr{$local\@$domain}; foreach (qw(roll.me.@example.com roll.you@example.com)) { print "$_: ", (/^$addr_spec$/o ? "true" : "false"), "\n"; }
実行した。
$ time perl rfc2822_addr_spec.pl roll.me.@example.com: false roll.you@example.com: true real 0m0.018s user 0m0.003s sys 0m0.005s
Boost.Xpressiveで書いてみた。適当にexpressionにしたので正しいかどうかは判らない。
#include <iostream> #include <string> #include <vector> #include <boost/assign.hpp> #include <boost/foreach.hpp> #include <boost/xpressive/xpressive.hpp> int main(int argc, char* argv[]) { using boost::xpressive::_ln; using boost::xpressive::_s; using boost::xpressive::_w; using boost::xpressive::range; using boost::xpressive::set; using boost::xpressive::sregex; const sregex atom(+(_w|(set='!','#','$','%','&','\'','*','+','/','=','?','^','`','{','}','~','|','-'))); const sregex dot_atom(atom >> *('.' >> atom)); const sregex quoted('"' >> *('\\' >> ~_ln | ~(set='\\','"')) >> '"'); const sregex local(dot_atom | quoted); const sregex domain_lit('[' >> *('\\' >> ~_s | set[range('\x21','\x5A') | range('\x5E','\x7E')]) >> ']'); const sregex domain(dot_atom | domain_lit); const sregex addr_spec(local >> '@' >> domain); const std::vector<std::string> data = boost::assign::list_of ("roll.me.@example.com") ("roll.you@example.com") ; std::cout << std::boolalpha; BOOST_FOREACH(const std::string& i, data) { std::cout << i << ": " << regex_match(i, addr_spec) << "\n"; } return 0; }
下記の環境でコンパイルした。ちなみにcodepad.orgではコンパイルできなかった。
- 2.8GHz Intel Core 2 Duo
- OCZ-VERTEX
- Mac OS X 10.6
- gcc version 4.2.1 (Apple Inc. build 5646) (dot 1)
- Boost 1.42.0
$ time g++ -fast rfc2822_addr_spec.cpp -o rfc2822_addr_spec real 0m9.188s user 0m8.617s sys 0m0.538s
実行した。
$ time ./rfc2822_addr_spec roll.me.@example.com: false roll.you@example.com: true real 0m0.019s user 0m0.001s sys 0m0.002s
「C++使いはもう正規表現をblogに書くな」と言われても良いレベルのコンパイル時間。たった35行のプログラムをコンパイルするのに10秒近くかかるとか、マゾかと。