4月29日に書いた日記の絵文字の正規表現が間違ってるという指摘を、
http://miau.s9.xrea.com/blog/index.php?itemid=678
というブログで受けた。
ん?この正規表現間違ってるな。
/\G(A*?)(?:B)|(?:C)/ みたいな構造になってるから、C が文字列先頭か B の直後に現れないとうまく除去できないのでは。
/\G(A*?)(?:B|C)/ みたいな構造にしないと。
やっぱりこうやって公開してると、間違ってたら誰か賢い人が指摘してくれるから良いやね。
で、簡単なチェックプログラム書いて試してみたところ、確かに、うまく除去できてなかった。
#!/usr/local/bin/perl use strict; use CGI; my $cgi = CGI->new; my $char = $cgi->param('char'); my $SJIS_CHARS = '(?:[\x00-\x7F\xA1-\xDF]|(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]))'; $char =~ s/\G(${SJIS_CHARS}*?)(?:\xF8[\x9F-\xFC]|\xF9[\x40-\x49\x50-\x52\x55-\x57\x5B-\x5E\x72-\x7E\x80-\xB0])|(?:\xF9[\xB1-\xFC])/$1/g; $char = $cgi->escapeHTML($char); print $cgi->header('text/html;charset=Shift_JIS'); print <<_; <HTML> <BODY> <FORM ACTION="${ENV{SCRIPT_NAME}}" METHOD="POST"> <INPUT TYPE="TEXT" NAME="char" VALUE="${char}"> <INPUT TYPE="SUBMIT"> </FORM> </BODY> </HTML> _
このCGIに「あαか○さαα○たな」と入力すると、見事に拡張絵文字が除去できてない。あらまあ。
ちなみにαが、
で拡張絵文字、○が、
で、基本絵文字。
上記ブログで指摘されているように、
$char =~ s/\G(${SJIS_CHARS}*?)(?:\xF8[\x9F-\xFC]|\xF9[\x40-\x49\x50-\x52\x55-\x57\x5B-\x5E\x72-\x7E\x80-\xB0])|(?:\xF9[\xB1-\xFC])/$1/g;
を、
$char =~ s/\G(${SJIS_CHARS}*?)(?:\xF8[\x9F-\xFC]|\xF9[\x40-\x49\x50-\x52\x55-\x57\x5B-\x5E\x72-\x7E\x80-\xB0]|\xF9[\xB1-\xFC])/$1/g;
にすると良いみたい。一応xを付けたのも書くと、
$char =~ s/ \G ( ${SJIS_CHARS}*? ) (?: \xF8[\x9F-\xFC] | \xF9[\x40-\x49\x50-\x52\x55-\x57\x5B-\x5E\x72-\x7E\x80-\xB0] ) | (?:\xF9[\xB1-\xFC]) /$1/gx;
が間違いで、
$char =~ s/ \G ( ${SJIS_CHARS}*? ) (?: \xF8[\x9F-\xFC] | \xF9[\x40-\x49\x50-\x52\x55-\x57\x5B-\x5E\x72-\x7E\x80-\xB0] | \xF9[\xB1-\xFC] ) /$1/gx;
だと正しく動くと。
ただ、
C が文字列先頭か B の直後に現れないとうまく除去できないのでは。
ってことではなくて、B(基本絵文字)とC(拡張絵文字)が混在してるとCが除去できないみたいでした。ただ、CがBの直後に現れる場合は除去できました。
きっとこれって、要するに、演算子の優先順位の問題ってことですかね。
print 'ABC' =~ /AB|CD/ ? "o\n" : "x\n";
はoになるけど、
print 'ACB' =~ /AB|CD/ ? "o\n" : "x\n";
はxになると。なんでかってーと、「A、それから次にBかC、そんでD」じゃなくて、「AB、もしくはCD」にマッチするから。だから、
print 'ACD' =~ /AB|CD/ ? "o\n" : "x\n";
とか、
print 'CAB' =~ /AB|CD/ ? "o\n" : "x\n";
はoになると。
お勉強になりました!