2010/10/11

NEC エンコード

[PRB] SHIFT - JIS と Unicode 間の変換問題

以前作った文字コードを判別してcp932を吐くスクリプト↓で一部の文字がマッピングされていないことに気がついた。
#### 実行環境チェック
#(eval {require Encode}) or die "please use perl 5.8.0 or higher version";
require Encode;
use Encode::Guess; # default only ascii/utf8/BOMed UTF
#use Encode::Guess qw/euc-jp shiftjis 7bit-jis/;一括で指定したい場合はココで。
binmode STDOUT, ":encoding(cp932)";
binmode STDERR, ":encoding(cp932)";
use utf8;

#参考ページ:http://www.kt.rim.or.jp/~kbk/perl-5.8/guess.html http://www.kt.rim.or.jp/~kbk/perl-5.8/supported.html

#### 引数チェック
($ARGV[1] and (!$ARGV[2])) || die "Please input 2 arguments";    #因数が2つでなければexit

#### 入出力ファイルチェック
(-r $ARGV[0]) or die "can't open $ARGV[0]: $!\n";
(-w $ARGV[1]) and warn "$ARGV[1] is over written\n";

#### 入力
open(INPUT,$ARGV[0]);    #入力OPEN
my $data=join '',<INPUT>;
close(INPUT);

#### UTF8にデコード
my $decoder = guess_encoding($data, qw/euc-jp cp932 iso-2022-jp big5-eten cp-936 gb12345-raw gb2312-raw/);
if(! ref($decoder)){
  $decoder = guess_encoding($data, qw/euc-jp cp932 iso-2022-jp/);
};
(! ref($decoder)) and die "can't guess encode of $ARGV[0]: $!\n";
my $data_utf8 = $decoder->decode($data);

###cp932で出力
open(OUTPUT,'>crlf:encoding(cp932',$ARGV[1]) or die "can't write: $!\n";    #出力OPEN
print OUTPUT $data_utf8;
close(OUTPUT);

で、
open(OUTPUT,'>crlf:encoding(cp932)',$ARGV[1]) or die "can't write: $!\n";    #出力

open(OUTPUT,'>crlf:encoding(sjis)',$ARGV[1]) or die "can't write: $!\n";    #出力
とすると上手く行きます。
・・・NEC エンコードとの互換性の話らしいのですが、知りませんでした。

そしてさらに上記のスクリプトではUTF8なファイルのBOMをそのまま吐く事になります。
上記のスクリプトを使っていて
\x{feff}
というのがファイル先頭に出たのであぁ、と気がつきました。

そんな解決法をgoogle先生に尋ねたら
Perl 5.8.x 以降で BOM を操作するモジュール ハードなソフトの話/ウェブリブログ
を教えてもらいました。
File::BOMというモジュールがあるとのこと。

・・・が、結局の所、
$data=~s/^\xEF\xBB\xBF//;
をやれば良いのでそっちで。

0 件のコメント:

コメントを投稿