Perlの文字コード変換の話 其の参
○ PerlIO
Perl 5.6 以降からは「入力 -> Perl内部処理 -> 出力」の橋渡しをするためのレイヤーとして
PerlIO というものが存在している。
PerlIO に対して使用するエンコードを指定することができる。
PerlIOに文字コードが指定されている場合、utf8フラグの立っている文字列をPerlIOに
渡すと、内部で適切な文字コード変換が行われる。
次のコードでは、STDOUT にshiftjis を指定することで、出力結果としてshiftjisの
文字列が表示される
use utf8;
use Encode;
binmode( STDOUT, ':encoding(shiftjis)' );my $a_data = "ほげほげ";
if( Encode::is_utf8( $a_data ) ){
print "utf8 on\n";
}else{
print "utf8 off\n";
}print $a_data . "\n";
結果(shiftjisで表示されているものとする)
utf8 on
ほげほげ
ここで、binmode( STDOUT, ':encoding(shiftjis)' ) が STDOUT のPerlIOをshiftjisとして
扱う宣言である。
仮に、この部分をコメントアウトした場合、次のような結果となる。
Wide character in print at ./test2.pl line 13.
utf8 on
縺サ縺偵⊇縺楷
一行目の、"Wide character in print ..."という警告文は、utf8フラグの立っている文字列を
文字コードの指定されていない PerlIO に渡した場合に表示される警告文である。
この警告文については、後に詳しく説明する。
PerlIO に文字コードを指定していなかった場合、utf8フラグの立っていない文字列
(便宜上バイトエンコード文字列と呼ぶ)を渡す必要がある。
utf8フラグの立っている文字列を、バイトエンコード文字列に変換するためには、Encode
モジュールの Encode::encode() を利用する。
以下に、サンプルコードを示す
use utf8;
use Encode;
#binmode( STDOUT, ':encoding(shiftjis)' );my $a_data = "ほげほげ";
if( Encode::is_utf8( $a_data ) ){
print "utf8 on\n";
}else{
print "utf8 off\n";
}print "data = " . $a_data . " \n"; # 警告が出ている部分
my $a_byte_str = Encode::encode( 'shiftjis', $a_data );
if( Encode::is_utf8( $a_byte_str ) ){
print "utf8 on\n";
}else{
print "utf8 off\n";
}print "byte = " . $a_byte_str . "\n";
実行結果は、次のようになる
Wide character in print at ./test2.pl line 15.
utf8 on
data = 縺サ縺偵⊇縺楷
byte = ほげほげ
このように Encode:encode() を用いることで、内部表現文字列をバイト文字列に変換
することが出来る。
ここでのポイントをまとめておくと
- PerlIOに文字コードが指定されている場合には、内部表現文字列を渡す
- PerlIOに文字コードが指定されている場合には、PerlIOが内部表現文字列を適切な形に変換する
- PerlIOに文字コードが指定されていない場合には、バイト文字列を渡す
ということである。