EUC-JPでマルチバイトを含む文字数を正確にカウントする
EUC-JPのシングルバイト文字のうち、コントロールコードを除いたASCII文字は[\x20-\x7E]。これはそのまま数えれば問題ない。
my $n = ($str =~ tr/\x20-\x7f/\x20-\x7f/);
一方、EUC-JPの2バイト文字は [\x8E\xA1-\xFE][\xA1-\xFE](うち\x8E[\xA1-\xDF]は半角カナ)、3バイト文字は \x8F[\xA1-\xFE][\xA1-\xFE] 。すなわち、1文字につき2バイトが[\x8E\xA1-\xFE]にマッチする。よって、
my $n = ($str =~ tr/\xa1-\xfe/\xa1-\xfe/) / 2;
は半角カナを含むマルチバイトの文字数。以上を組み合わせて、
my $str = '日本語文字abcdeあいうえおアイウエオ'; my $n = ($str =~ tr/\x8e\xa1-\xfe/\x8e\xa1-\xfe/) / 2 + ($str =~ tr/\x20-\x7f/\x20-\x7f/); print "$n\n"; # 結果は20