ユーザ用ツール

サイト用ツール


perl:encoding

Perlの文字化け防止

フラグ付き?

  • 「UTF-8フラグ付き文字列」と「UTF-8文字列」は別物。
  • 「UTF-8フラグ付き文字列」はPerlがマルチバイト文字列を扱うとき内部表現形式。
  • 「UTF-8文字列」は、UTF-8という文字エンコーディング規則でエンコードされたデータ。
  • 「UTF-8文字列」は、Perlの内部表現形式ではないので、単なるバイト列として処理される。
  • 「UTF-8フラグ付き文字列」はPerlの内部表現なので、外部にそのまま出力してはいけない。

対策

  • ソースコードをUTF-8で書き、use utf8を宣言
  • 外部から入力する文字列はデコードする
  • 外部に出力する文字列はエンコードする

外部から入力されるUTF-8やShift_JISなどの文字列を、デコードしてPerlの内部表現である「UTF-8フラグ付き文字列」に変換する。マルチバイト文字列はPerl内では全て「UTF-8フラグ付き文字列」で処理する。出力時に「UTF-8フラグ付き文字列」からUTF-8やShift_JISなどの形式にエンコードする。

こうすることで単に文字化け防止になるだけでなく、各種の関数がバイトデータではなく文字列データとして扱えるようになる。

ソースコードをUTF-8で書き、use utf8を宣言

use utf8 はソースコード中に直接書かれた文字列リテラルを、「UTF-8フラグ付き文字列」にデコードする。

print length("ほげ");   // 6

“ほげ” は「UTF-8文字列」であるため、length関数はバイト数を返す。

use utf8;
print length("ほげ");   // 2

use utf8で、“ほげ”が「UTF-8文字列」から「UTF-8フラグ付き文字列」にデコードされ、length関数は文字数を返す。

外部から入力する文字列をデコード

標準入力のデータをデコードする

binmode STDIN,  ":utf8";
 
# 入力と宣言の文字コードが一致していれば、正しくUTF-8フラグ付き文字列にデコードされ文字数が取得される
print length(<STDIN>);

標準入力が Shift_JIS の場合

binmode STDIN   ":encoding(shiftjis)";

外部に出力する文字列をエンコード

UTF-8フラグ付き文字列を出力しようとすると警告が出るので、正しくエンコードする必要がある。

標準出力のデータをエンコードする

# ソースコードはUTF-8で書き、リテラルはUTF-8フラグ付き文字列にデコードする
use utf8;
my $hoge = "ほげ";
 
# UTF-8フラグ付き文字列を標準出力に書き出すときに、CP932にエンコードする
binmode STDOUT, ":encoding(cp932)";
print $hoge;  
perl/encoding.txt · 最終更新: 2011/07/12 09:57 by nullpon