Encode.pm および Jcode.pm を使った場合の解説については、 こちらを参照してください。
Perl 5.005 および Perl 5.6.1 では、Encode.pm モジュールが利用できませんが、 Unicode::Map モジュールを利用することで Encode::from_to 関数と同様に多言語の変換処理が可能です。
Unicode::Map の内部コードは UCS2 になります。 標準では UTF8 はサポートされないため、 UTF8 を利用したい場合は UCS2〜UTF8 間の変換に Unicode::String を併用します。 そのため、今回のように UTF8 を Shift_JIS に変換する場合、 UTF8→UCS2→Shift_JIS と順に変換させることになります。
このとき、UTF8→UCS2 の変換時にはデータ消失はありませんが、 UCS2→Shift_JIS の変換時には UCS2(Unicode) に表現できて Shift_JIS で表現できない文字は 削除されてしまいます。
#!/usr/bin/perl use Unicode::Map; use Unicode::String; my $utf8 = "\xE9\x84\xA7\xE5\xB0\x8F\xE5\xB9\xB3"; # とう小平(UTF8) my $unistr = new Unicode::String(); $unistr->utf8( $utf8 ); $ucs2 = $unistr->utf16(); # いったんUCS2に変換 my $unimap = new Unicode::Map("Shift_JIS"); $sjis = $unimap->from_unicode( $ucs2 ); # さらにShift_JISに変換 print $sjis, "\n";
この結果は、「鄧」の字は削除され「小平」になってしまいます。(コダイラ?)
Unicode::Map でも Encode::FB_XMLCREF のように &#xHHHH; の形式にエスケープする パッチプログラムを作成しました。
下記の手順でパッチを適用・インストールします。
$ wget ftp://ring.ocn.ad.jp/pub/lang/perl/CPAN/modules/by-module/Unicode/Unicode-Map-0.112.tar.gz $ wget http://www.kawa.net/works/jcode/unimap-escape-20041025.patch $ tar zxf Unicode-Map-0.112.tar.gz $ patch -p0 < unimap-escape-20041025.patch $ cd Unicode-Map-0.112 $ perl Makefile.PL && make # make install
このパッチを適用した Unicode::Map では、
が &#xHHHH; 形式にエスケープされます。先と同じプログラム
#!/usr/bin/perl use Unicode::Map; use Unicode::String; my $utf8 = "\xE9\x84\xA7\xE5\xB0\x8F\xE5\xB9\xB3"; # とう小平(UTF8) my $unistr = new Unicode::String(); $unistr->utf8( $utf8 ); $ucs2 = $unistr->utf16(); # いったんUCS2に変換 my $unimap = new Unicode::Map("Shift-JIS"); $sjis = $unimap->from_unicode( $ucs2 ); # さらにShift_JISに変換 print $sjis, "\n";
を実行した結果は、『鄧小平』となってエスケープされました。
(※ Unicode::Map では、"Shift_JIS"でなく"Shift-JIS"と指定します。2005/01/17訂正)
もちろん、Shift_JIS に含まれる通常の文字については、 正しく Shift_JIS で出力されます。 また、"Shift-JIS"でなくて"CP932"や"EUC-JP"を指定した場合は、 こちらのエンコーディングでは「鄧」の字を利用できるため、 『鄧小平』とならずに『鄧小平』に変換できます。
トラックバックURL:http://www.kawa.net/service/tb/ajaxtb.cgi/works/jcode/unimap-escape.html
Kawa.netxp © Copyright 2004 Yusuke Kawasaki