WINDOWSでのPerl漢字処理について考えました。
ここのところ、漢字処理について考えていました。
以下は、間違えやツッコミ所が満載かもしれませんが、書いてみます。
結論としては、漢字コードの第二バイトが1バイト文字(\や@やアルファベット等)とダブルことがあるshiftjisは、まずNGです。
また、漢字が連続した場合に2文字の境界で下位バイトと上位バイトで、たまたま意味のある漢字になってしまうeuc-jpもNGです(shiftjisでも同様)。
というか、shiftjisもeuc-jpもバイト列で処理を考えているからで、バイト列ではもともと漢字処理が不可能に近いのですね。たぶん。
そこで、バイト列でなく、文字列として処理を行い、かつ、1バイト文字や制御文字とダブらないということで、Unicode(utf-8)の出番になるわけです。
一方、WINDOWSでは、まだshiftjisの世界です。
なので内部コードはUnicode(utf-8)で文字列として処理を行い、WINDOWSの世界へはencodingしてshiftjisにするというのが、いいのではないでしょうか・・・。
ということで、内部的にはutf8フラグを付加することによりバイト列でなく文字列として認識させ、コードは1バイト文字とダブらないUnicode(utf-8)を使う。
以下のサンプルは、ソースコードをshiftjisとして書き、『use encoding 'shiftjis';』として、内部的にすべてのリテラルにutf8フラグを付加することによりバイト列でなく文字列として認識させ、内部コードをutf-8とする。
そして、『use encoding 'shiftjis';』は、また、標準入出力を内部のutf8と外部のshiftjisでのencodingを行います。
標準入出力以外の標準エラーやファイルハンドルは、binmode関数を使って内部のutf-8と外部のshiftjisでのencodingを行います。
とにかく、ポイントは2つ。
サンプルソース
use strict; use warnings; use encoding 'shiftjis'; binmode STDERR, ':encoding(shiftjis)'; open(FH_IN, 'sjis_in.txt'); open(FH_OUT, '>sjis_out.txt'); binmode FH_IN, ":encoding(shiftjis)"; binmode FH_OUT, ":encoding(shiftjis)"; while (<FH_IN>) { print FH_OUT $_; print unpack('H*', $_), "\n"; print $_; } close(FH_OUT); close(FH_IN); print "----------------------\n"; while (<STDIN>) { print $_; } print "表示 充分 ス 十分";
上記をすすめて、アレなんですが、ソースコードはutf-8で書き、utf8プラグマを指定するのが、Perlの方向性としては、一番いいらしいです。