2009年7月10日金曜日

[Perl] スペースを正しく取り除く

PerlであるEUC-JPの文字列から全角スペースを取り除いてみる。

my $original = ' ぁ?';

my $str1 = $original;
$str1 =~ s/\xA1\xA1//g;
print qq(str1: $str1\n);

my $str2 = $original;
$str2 = Encode::decode('euc-jp', $str2);
$str2 =~ s/ //g;
$str2 = Encode::encode('euc-jp', $str2);
print qq(str2: $str2\n);

# 本スクリプトの文字コードはEUC-JPとする
2通りのやり方結果どちらも「ぉ」が出力される。

解説

「 ぁ?」をバイトコードで表すと「\xA1\xA1\xA4\xA1\xA1\xA9」。
全角スペースは「\xA1\xA1」なので、「\xA1\xA1\xA4\xA1\xA1\xA9」の
赤字部分がトリミングされて「\xA4\xA9」が残る。
「\xA4\xA9」は「ぉ」なのだ!!

回避方法

バイト単位で処理されるとこうなってしまうので、、
EUC-JP文字を1字ずつマッチングさせていく必要がある。
my $char_eucjp_regexp = '(?:[\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1-\xFE][\xA1-\xFE])'; # EUC-JP 1文字のバイトコード正規表現
my $original = ' ぁ?';

my $str = $original;
$str =~ s/\G($char_eucjp_regexp*?)\xA1\xA1/$1/g;
print qq(str: $str\n);

# 本スクリプトの文字コードはEUC-JPとする
これで晴れて「ぁ?」が表示される。
意外と気付かないまま書いているケースがあるので注意しよう。

0 件のコメント: