Kawa.netxp Shift_JIS に含まれない文字をエスケープ(Unicode::Map編)

Encode.pm および Jcode.pm を使った場合の解説については、 こちらを参照してください。

Perl 5.005/5.6.1+Unicode::Map

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";

この結果は、「鄧」の字は削除され「小平」になってしまいます。(コダイラ?)

Perl 5.005/5.6.1+Unicode::Map+パッチ適用

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";

を実行した結果は、『&#x9127;小平』となってエスケープされました。
(※ Unicode::Map では、"Shift_JIS"でなく"Shift-JIS"と指定します。2005/01/17訂正)

もちろん、Shift_JIS に含まれる通常の文字については、 正しく Shift_JIS で出力されます。 また、"Shift-JIS"でなくて"CP932"や"EUC-JP"を指定した場合は、 こちらのエンコーディングでは「鄧」の字を利用できるため、 『&#x9127;小平』とならずに『鄧小平』に変換できます。

補足

その他のモジュール・ライブラリ

コメントはこちらへ by AjaxCom

このページへのトラックバック by AjaxTB

トラックバックURL:http://www.kawa.net/service/tb/ajaxtb.cgi/works/jcode/unimap-escape.html

Kawa.netxp © Copyright 2004 Yusuke Kawasaki