読者です 読者をやめる 読者になる 読者になる

Perlがくしゅう帳(Rubyも)

プログラミングの勉強会の参加記録や学んだことなど。 twitter ID : @tomcha_で活動しています。 最近は主にPerl関連の勉強会やコミュニティに参加しています。移転前のブログはこちら->http://ruby.doorblog.jp/

Perlでの文字エンコード変換について

今朝通勤電車の中でtwitterのTLのを見ていた時、ハッシュタグ #Perl入学式 で、エンコードに関する質問がされていたので、

 

 

電車の中で考えてた事を実際にコードで書いて試してみました。

 

perl入学式で習った知識

  • 入力と出力(とエラー出力)のエンコードは、それぞれ個別に指定する。おまじないとして習った標準入力、標準出力、エラー出力の記述方法は、

   binmode STDIN,":encoding(utf8)";

   binmode STDOUT,":utf8";

   binmode STDERR,":utf8";

  • STDINで設定しているのは、perl内部に標準入力から受け取るテキストが何で書かれているか、つまりどの文字コード書式の想定で読み込むか。逆にSTDOUTはどの文字コード書式で書き込むかを設定している。

ググって調べた事

 参考にしたページ -> 文字コードの指定 - ファイル操作 - Perl入門

  • 文字コードの表記は、UTF8は":utf8"、それ以外は":encoding(文字コード)"と書く。(という事は、":encoding(utf8)"はただの":utf8"表記でOKっぽい?)
  • ファイル入出力のエンコード指定の記述方法は、

        binmode ファイルハンドル,":文字コード";

 

なので、質問に対して考えたことは、「eucで書かれたテキストを読み込むには、binmode ファイルハンドル(euc-jp)で読み込んで、perlの中で内部処理後、binmode 別のファイルハンドル(utf8)で書き込めばutf8に変換できるのではないかということ。

 

実験用のコードを書いて、euc-jpで書かれたテキストを使って実験してみました。

gist6459410

 

コード実験結果

  • 「:utf8でオープンして読み込み」又は「:utf8でオープンして読み込み」「:utf8でオープンして書き込み」

コード内でDumpした出力

f:id:tomcha0079:20130906125446p:plain

ファイルに書き込まれたテキスト 

f:id:tomcha0079:20130906130430p:plain

・・・ダメダメですね。euc-jpのファイルをちゃんと読み込めていないので、内部でも最終出力でも文字化けしてしまってます。

 

  • 「:encoding(euc-jp)でオープンして読み込み」「:utf8でオープンして書き込み」

コード内でDumpした出力

 f:id:tomcha0079:20130906125442p:plain

ファイルに書き込まれたテキスト

f:id:tomcha0079:20130906130457p:plain

・・・きちんと読み込まれているので、内部処理もファイル書き込みもバッチリです。

 

そういえば、昨年のPerl入学式#2で、文字コードについて、binmodeのutf8とPerl内部で使われているutf8は別物だと教えてもらった記憶があるのですが、binmodeで書かれる「:encoding(hoge)」は、「hogeに変換(エンコード)する」というより、「hogeで書かれた(書き込む)ていでopenすると設定する」と捉えるとわかりやすい感じでしょうか。