utf-8フラグ

最終更新日時:2011-07-15 00:00:00
Perl

概要


※私自身utf-8フラグをきちんと理解していないので、あくまでも参考程度で(/_\;)

Perl-5.8以降では、Perlの内部のエンコーディングはutf-8となりました。
内部的にutf-8として扱っている文字列にはutf-8フラグというものが付きます。
そしてこれが厄介なのですが、普通にutf-8の文字列をプログラム中に書き込み、それを変数に格納したりしても、その文字列にはutf-8フラグは付きません。
しかしながら、utf-8フラグの有無が混在したものを表示したりすると文字化けが起きたりしますので、utf-8フラグに対する処理は避けては通れません。

また、utf-8フラグ付きの文字列を普通に出力しようとすると、以下のような警告が出ることがあります。

 Wide character in print at xxxx.pl line 11.


対応方法


いろいろあり、その時々によってベストな方法があるのと、私自身深い理解が無いのでとりあえず列挙だけ(/_\;)

utf-8フラグの有無を確認。

 utf8::is_utf8('xxxx')


エンコーディングを指定すると、utf-8フラグが付きます。
ソースは指定したエンコーディングで記述する必要があります。

 use encoding 'euc-jp';


utf-8フラグ付きでソースを記述するように指定します。
ソースは、utf-8で記述する必要があります。

 use utf8;


明示的にエンコードしてutf-8フラグを落とす。

 use Encode;
 Encode::encode('utf8', xxxx);


明示的にIOレイヤに対してエンコーディングを指定する。

 binmode(STDOUT, ":utf8");


ここまでいろいろ紹介してきましたが、何も考えずUnicode::RecursiveDowngradeを使ってutf-8フラグを落としてしまうのが、現状では一番楽ちんかつ確実かと思います。

 use Unicode::RecursiveDowngrade
 Unicode::RecursiveDowngrade->new->downgrade($hash_ref);


日本語文字数のカウント


utf-8フラグがついていると、length() で日本語の文字数を正確にカウントすることが出来ます。

 use Encode qw(decode);
 my $str = 'テストです。';
 print length($str), "\n";
 print length(decode('utf-8', $str)), "\n";


実行結果。

 18
 6


お問い合わせは 掲示板 にて。