【perlメモ】perl5.8系utf8関連の自分用まとめ

とにかく慣れるまでめんどくさい。最初は訳がわからないが判っててくれば便利。jcode.plやjcode.pm時代より面倒でとっつきにくいのはたしか。こういう事を気にしないでコードを書ける日が来るといいな。

基本的には下の記事を抑えておけば大丈夫なはず。

最近はよほど古いソースのメンテでもなければutf8で書くと思うので、下の3行はお決まり。

use strict;
use warnings;
use utf8;

必要に応じて下の様にしたりする。

use strict;
use warnings;
use utf8;
use Encode qw/decode_utf8 encode_utf8 from_to/;
use Encode::Guess qw/ascii euc-jp shiftjis 7bit-jis/;

 

$ret = utf8::is_utf8($str);

utf8フラグが立っているかチェック。utf8フラグonの場合trueを返す。

utf8::encode($str);

utf8フラグをoffする。引数を直接変更する。

utf8::decode($str);

utf8フラグをonする。引数を直接変更する。

$ret = Encode::encode(“euc-jp”,$str);

utf8フラグがonの文字列を指定した文字列に変換しutf8フラグをoffにする。
utf8フラグがonの内部文字列(utf8)を指定した文字コードに変換しutf8フラグをoffする。

$ret = Encode::decode(“cp932”,$str);
$ret = Encode::decode(“Guess”,$str);

指定した文字コードで、指定した文字のutf8フラグをonにする。※文字コードの変換をしないことに注意。ここを勘違いするとハマる。
指定した字コード、指定した文字コードの文字列から内部コード(utf8)に変換してutf8フラグをonする。

Encode::from_to($str,”utf8”,”euc-jp”);

utf8フラグがoffの指定した文字列を指定した文字コードから文字コードへ変換する。引数が直接変化する。utf8フラグは変化しない。

$ret = Encode::encode_utf8($str);

指定した文字列のutf8フラグをoffする。

$ret = Encode::decode_utf8($str);

指定した文字列のutf8フラグをonする。既にonになってる部分についてはそのままコピーされる。不正な文字については\x{fffd}に置き換える。

※utf8::encodeとEncode::encodeを混同しないようにする。
とくにuse Encode qw/encode/;などして、パッケージ名を省略している場合には注意。

※セキュリティを考慮して内部のリテラルな文字列にはdecode、外部からの入力には不正な文字を[\x{fffd}]に置き換えるdecode_utf8を使う。なるべくdecode_utf8を使っとけばOK?

 


Encode::Guess

Jcodeのように元の文字コードがわからない状態からの文字コードの自動変換はEncode::Guessを使えば可能であるが、文字列が短いと誤認識しやすい。判定する場合例えば単語ではなくページ全体を渡して変換したほうが失敗しない。なるべくGuessに頼らない方が無難。どうしても単語単位でやる必要があるならJcode.pmを使ったほうがいいかも知れない(非推奨)。

use Encode::Guess qw/ascii euc-jp shiftjis 7bit-jis/;

Encode::from_to($str,’Guess’,”euc-jp”);

上記の場合[Use of uninitialized value]エラーが出る場合

use Encode::Guess qw/ascii euc-jp shiftjis 7bit-jis/;

$str = decode("Guess",$str);

こっちの方がいいかも


Wide caractor in print

test01.pl(utf8)

#!/usr/bin/perl

use Strict;
use Warnings;
use utf8;

print "あいうえお\n";

実行結果

F:\kumacchi\MyProgram\perl\sample\utf8>perl test01.pl
Wide character in print at test01.pl line 7.
縺ゅ>縺・∴縺・

F:\kumacchi\MyProgram\perl\sample\utf8>

Wide character問題はこう直す。
test02.pl(utf8)

#!/usr/bin/perl

use Strict;
use Warnings;
use utf8;

binmode STDOUT,’:utf8′;
print "あいうえお\n";

実行結果

F:\kumacchi\MyProgram\perl\sample\utf8>perl test02.pl
縺ゅ>縺・∴縺・

F:\kumacchi\MyProgram\perl\sample\utf8>

ついでにcp932(マイクロソフト拡張Shiftjis)に変換して出力するにはこう直す。
test03.pl(utf8)

#!/usr/bin/perl

use Strict;
use Warnings;
use utf8;

binmode STDOUT,’:encoding(cp932)’;
print "あいうえお\n";

実行結果

F:\kumacchi\MyProgram\perl\sample\utf8>perl test03.pl
あいうえお

F:\kumacchi\MyProgram\perl\sample\utf8>

 

ファイルに出力するときも上記と同様。

test04.pl(utf8)

#!/usr/bin/perl

use Strict;
use Warnings;
use utf8;
use Encode;

$/ = undef;
open(FILE,"test03.pl");
my $str = <FILE>;
close(FILE);
$/ = "$\n";

$str = Encode::decode_utf8($str);

binmode STDOUT,’:encoding(cp932)’;
print $str;

実行結果

F:\kumacchi\MyProgram\perl\sample\utf8>perl test04.pl
#!/usr/bin/perl

use Strict;
use Warnings;
use utf8;

binmode STDOUT,’:encoding(cp932)’;
print "あいうえお\n";

F:\kumacchi\MyProgram\perl\sample\utf8>

utf8フラグをonにした状態で読み込む。

#!/usr/bin/perl
use Strict;
use Warnings;
use utf8;

$/ = undef;
open(FILE,"<:utf8","test03.pl");
my $str = <FILE>;
close(FILE);
$/ = "$\n";

binmode STDOUT,":encoding(cp932)";
print $str;

実行結果

F:\kumacchi\MyProgram\perl\sample\utf8>perl test05.pl
#!/usr/bin/perl

use Strict;
use Warnings;
use utf8;

binmode STDOUT,’:encoding(cp932)’;
print "あいうえお\n";

F:\kumacchi\MyProgram\perl\sample\utf8>

 

読み込むファイルがShiftjis(CP932)の時utf8に変換してutf8フラグをonして読み込む。

test06.pl

#!/usr/bin/perl
use Strict;
use Warnings;
use utf8;
use Encode;

$/ = undef;
open(FILE,"<:encoding(cp932)","shiftjis.txt");
my $str = <FILE>;
close(FILE);
$/ = "$\n";

if(utf8::is_utf8($str)){
    print "—– utf8 flag on\n";
}

binmode STDOUT,":encoding(cp932)";
print $str;

実行結果

F:\kumacchi\MyProgram\perl\sample\utf8>perl test06.pl
—– utf8 flag on
あいうえお
かきくけこ
さしすせそ

F:\kumacchi\MyProgram\perl\sample\utf8>

タグ :