Perlでの文字エンコード変換について
今朝通勤電車の中でtwitterのTLのを見ていた時、ハッシュタグ #Perl入学式 で、エンコードに関する質問がされていたので、
EUCで保存されているテキストファイルをUTF-8で保存したい場合、 ファイルオープン時に:encoding(UTF-8)を指定するだけで 自動的にEUC->UTF-8にエンコードしてから書き出してくれるんでしょうか? #Perl入学式
— 猊下 (@u1ogawa) September 4, 2013
電車の中で考えてた事を実際にコードで書いて試してみました。
perl入学式で習った知識
- 入力と出力(とエラー出力)のエンコードは、それぞれ個別に指定する。おまじないとして習った標準入力、標準出力、エラー出力の記述方法は、
binmode STDIN,":encoding(utf8)";
binmode STDOUT,":utf8";
binmode STDERR,":utf8";
- STDINで設定しているのは、perl内部に標準入力から受け取るテキストが何で書かれているか、つまりどの文字コード書式の想定で読み込むか。逆にSTDOUTはどの文字コード書式で書き込むかを設定している。
ググって調べた事
参考にしたページ -> 文字コードの指定 - ファイル操作 - Perl入門
- 文字コードの表記は、UTF8は":utf8"、それ以外は":encoding(文字コード)"と書く。(という事は、":encoding(utf8)"はただの":utf8"表記でOKっぽい?)
- ファイル入出力のエンコード指定の記述方法は、
なので、質問に対して考えたことは、「eucで書かれたテキストを読み込むには、binmode ファイルハンドル(euc-jp)で読み込んで、perlの中で内部処理後、binmode 別のファイルハンドル(utf8)で書き込めばutf8に変換できるのではないかということ。
実験用のコードを書いて、euc-jpで書かれたテキストを使って実験してみました。
コード実験結果
- 「:utf8でオープンして読み込み」又は「:utf8でオープンして読み込み」「:utf8でオープンして書き込み」
コード内でDumpした出力
ファイルに書き込まれたテキスト
・・・ダメダメですね。euc-jpのファイルをちゃんと読み込めていないので、内部でも最終出力でも文字化けしてしまってます。
- 「:encoding(euc-jp)でオープンして読み込み」「:utf8でオープンして書き込み」
コード内でDumpした出力
ファイルに書き込まれたテキスト
・・・きちんと読み込まれているので、内部処理もファイル書き込みもバッチリです。
そういえば、昨年のPerl入学式#2で、文字コードについて、binmodeのutf8とPerl内部で使われているutf8は別物だと教えてもらった記憶があるのですが、binmodeで書かれる「:encoding(hoge)」は、「hogeに変換(エンコード)する」というより、「hogeで書かれた(書き込む)ていでopenすると設定する」と捉えるとわかりやすい感じでしょうか。