The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

名称

ShiftJIS::CP932::MapUTF - Microsoft CP-932とUnicodeとの変換

概要

    use ShiftJIS::CP932::MapUTF qw(:all);

    $utf8_string  = cp932_to_utf8($cp932_string);
    $cp932_string = utf8_to_cp932($utf8_string);

説明

マイクロソフトウィンドウズ (Microsoft Windows) コードページ 932 (CP-932) のテーブルは 7915 文字からなります。

    JIS X 0201 一バイト文字(191 文字)
    JIS X 0208 二バイト文字(6879 文字)
    NEC特殊文字(83 文字、13区)
    NEC選定IBM拡張文字(374 文字、89〜92区)
    IBM拡張文字(388 文字、115〜119区)

この表は、往復変換できない二重定義文字を含んでいます。 これらの二重定義文字はベンダー(NEC および IBM)定義の拡張文字のためです。 例えば、Unicode の U+2252 に対応付けられる文字は二個あります。 つまり、JIS X 0208 文字の 0x81e0 と NEC 特殊文字の 0x8790 です。

実際、CP-932 の 7915 文字を Unicode の 7517 文字に対応付けなければなりません。 このため、398 の往復変換できない対応関係が存在します。

このモジュールは、CP-932 から Unicode に、また、 Unicode から CP-932 に、適切に変換する関数を提供します。

CP-932 から Unicode への変換

第一引数がレファレンスの場合、それは SJIS_CALLBACK として、 Unicode への対応がない CP-932 文字の処理に用いられます。 (STRING にレファレンスを与えることはできません。)

SJIS_CALLBACK が与えられている場合、 第二引数が STRING として用いられます。 さもなければ第一引数が STRING になります。

もし SJIS_CALLBACK が与えられていない場合、 Unicode への対応がない CP-932 文字は黙って削除され、 部分文字は一バイト分跳ばされます。 SJIS_CALLBACK として、常に空文字列を返す コードリファレンス (sub {''}) が渡されたかのように動作します。

今のところ、SJIS_CALLBACK としては、 コードリファレンスのみが使えます。 コードリファレンスの返り値がマッピングのない文字の代わりに挿入されます。

コードリファレンス SJIS_CALLBACK は、一個以上の引数とともに 呼び出されます。マッピングのない文字が部分的な二バイト文字 (第一バイトのみの一バイト長の文字列)の場合、 第一引数は未定義値(undef)になり、 第二引数はバイトを表す符号なし整数値になります。 部分文字でなければ、第一引数は、文字を表す文字列になります。

デフォルトでは、部分的な二バイト文字は、文字列(STRING)の末尾にのみ 現れる可能性があり、文字列の先頭や途中には現れません (SJIS_OPTION't' も参照のこと)。

    my $sjis_callback = sub {
        my ($char, $byte) = @_;
        return function($char) if defined $char;
        die sprintf "found partial byte 0x%02x", $byte;
    };

上記の例で、$char としては、"\x80", "\x82\xf2", "\xfc\xfc", "\xff" などがあり得ます。

SJIS_CALLBACK の返り値は、変換先の形式に合わせなければなりません。 例えば、cp932_to_utf16be() とともに UTF-8 を返す SJIS_CALLBACK を使ってはいけません。 つまり、UTF ごとに、SJIS_CALLBACK を用意する必要があります。

SJIS_OPTIONSTRING の後におくことができます。 これらは 'tg''gst' のように組み合わせることも できます(順序は任意です)。

    'g'    CP-932 外字(ユーザ定義文字)[0xF040〜0xF9FC (95〜114区)] を
           Unicode の PUA [0xE000〜0xE757] に変換します(1880 文字)。

    's'    CP-932 未定義の一バイト文字を以下のように変換します。
           0x80 => U+0080,  0xA0 => U+F8F0,
           0xFD => U+F8F1,  0xFE => U+F8F2,  0xFF => U+F8F3.

    't'    第二バイトの範囲 [0x40..0x7E, 0x80..0xFC] をチェックします。
           例えば "\x81\x39" はデフォルトでは未定義の二バイト文字と
           みなしますが、't' を用いると、部分文字バイト 0x81 の後に
           一バイト文字 "\x39" が続いたものとみなします。
cp932_to_utf8([SJIS_CALLBACK,] STRING [, SJIS_OPTION])

CP-932 を UTF-8 に変換します。

cp932_to_unicode([SJIS_CALLBACK,] STRING [, SJIS_OPTION])

CP-932 を Unicode に変換します。 (SVf_UTF8 フラグ付きの Perlの内部形式, perlunicode を参照。)

この関数は Perl 5.6.1 以降、かつ XS 版でのみ提供されます。

cp932_to_utf16le([SJIS_CALLBACK,] STRING [, SJIS_OPTION])

CP-932 を UTF-16LE に変換します。

cp932_to_utf16be([SJIS_CALLBACK,] STRING [, SJIS_OPTION])

CP-932 を UTF-16BE に変換します。

cp932_to_utf32le([SJIS_CALLBACK,] STRING [, SJIS_OPTION])

CP-932 を UTF-32LE に変換します。

cp932_to_utf32be([SJIS_CALLBACK,] STRING [, SJIS_OPTION])

CP-932 を UTF-32BE に変換します。

Unicode から CP-932 への変換

二重定義文字はすべて、Microsoft PRB Q170559 に従って変換されます。 例えば U+2252"\x87\x90" ではなく "\x81\xE0" に変換されます。

第一引数がレファレンスの場合、それは UNICODE_CALLBACK として、 CP-932 への対応がない Unicode 文字の処理に用いられます。 (STRING にレファレンスを与えることはできません。)

UNICODE_CALLBACK が与えられている場合、 第二引数が STRING として用いられます。 さもなければ第一引数が STRING になります。

もし UNICODE_CALLBACK が与えられていない場合、 CP-932 への対応がない Unicode 文字は黙って削除され、 また、部分文字は一バイト分跳ばされます。 UNICODE_CALLBACK として、常に空文字列を返す コードリファレンス (sub {''}) が渡されたかのように動作します。

今のところ、UNICODE_CALLBACK としては、 コードリファレンスのみが使えます。 そのコードリファレンスの返り値が マッピングのない文字の代わりに挿入されます。

コードリファレンス UNICODE_CALLBACK は、 一個以上の引数とともに呼び出されます。マッピングのない文字が 部分的文字(不正なバイト)の場合、第一引数は未定義値(undef)になり、 第二引数はバイトを表す符号なし整数値になります。 部分文字でなければ、第一引数は、Unicode文字の符号位置を表す 符号なし整数値になります。

例えば、CP-932 への対応がない文字を HTML 4.01 の数値文字参照に 変換する方法を示します。

    sub toHexNCR {
        my ($char, $byte) = @_;
        return sprintf("&#x%x;", $char) if defined $char;
        die sprintf "illegal byte 0x%02x was found", $byte;
    }

    $cp932 = utf8_to_cp932   (\&toHexNCR, $utf8_string);
    $cp932 = unicode_to_cp932(\&toHexNCR, $unicode_string);
    $cp932 = utf16le_to_cp932(\&toHexNCR, $utf16le_string);

UNICODE_CALLBACK の返り値は CP-932 として正しくある必要があります。

UNICODE_OPTIONSTRING の後におくことができます。 これらは 'fg''gsf' のように組み合わせることも できます(順序は任意です)。

    'g'    CP-932 外字(ユーザ定義文字)[0xF040〜0xF9FC (95〜114区)] に
           Unicode の PUA [0xE000〜0xE757] から変換します(1880 文字)。

    's'    CP-932 未定義の一バイト文字の対応付けを追加します。
           U+0080 => 0x80,  U+F8F0 => 0xA0,
           U+F8F1 => 0xFD,  U+F8F2 => 0xFE,  U+F8F3 => 0xFF.

    'f'    Unicode から CP-932 への幾つかの代用的な変換 (fallbacks) を
           追加します。マッピングが追加される文字は、latin-1 領域
           [U+00A0..U+00FF] のうちの幾つかの文字と、平仮名のヴ [U+3094,
           片仮名のヴ (0x8394) になります] です。
utf8_to_cp932([UNICODE_CALLBACK,] STRING [, UNICODE_OPTION])

UTF-8 を CP-932 に変換します。

unicode_to_cp932([UNICODE_CALLBACK,] STRING [, UNICODE_OPTION])

Unicode を CP-932 に変換します。

この Unicode は、Perl の内部形式(perlunicode 参照)。 SVf_UTF8 フラグ付きでない場合、ISO 8859-1 (latin1) 文字列として Unicode に upgrade されます。

この関数は Perl 5.6.1 以降、かつ XS 版でのみ提供されます。

utf16_to_cp932([UNICODE_CALLBACK,] STRING [, UNICODE_OPTION])

UTF-16 (BOM 付きまたは無し) を CP-932 に変換します。

utf16le_to_cp932([UNICODE_CALLBACK,] STRING [, UNICODE_OPTION])

UTF-16LE を CP-932 に変換します。

utf16be_to_cp932([UNICODE_CALLBACK,] STRING [, UNICODE_OPTION])

UTF-16BE を CP-932 に変換します。

utf32_to_cp932([UNICODE_CALLBACK,] STRING [, UNICODE_OPTION])

UTF-32 (BOM 付きまたは無し) を CP-932 に変換します。

utf32le_to_cp932([UNICODE_CALLBACK,] STRING [, UNICODE_OPTION])

UTF-32LE を CP-932 に変換します。

utf32be_to_cp932([UNICODE_CALLBACK,] STRING [, UNICODE_OPTION])

UTF-32BE を CP-932 に変換します。

輸出

デフォルト:

    cp932_to_utf8     utf8_to_cp932
    cp932_to_utf16le  utf16le_to_cp932
    cp932_to_utf16be  utf16be_to_cp932

    cp932_to_unicode  unicode_to_cp932 (XS のみで提供されます)

要求されれば:

    cp932_to_utf32le  utf32le_to_cp932
    cp932_to_utf32be  utf32be_to_cp932
                      utf16_to_cp932 [*]
                      utf32_to_cp932 [*]

[*] これらと対応すべき cp932_to_utf16() および cp932_to_utf32() は未実装です。まだ SJIS_CALLBACK の返り値についてもう少し検討が 必要と考えています。 (文字列の連結に BOM の認識と処理が必要となるでしょう。)

注意事項

このモジュールの Pure Perl 版はワイド文字(perlunicode を参照)を 理解できません。必要なら、Perl 5.7 以降の utf8::decode/utf8::encodeutf8 を参照)を使ってください。

作者

SADAHIRO Tomoyuki <SADAHIRO@cpan.org> (貞廣 知行)

Copyright(C) 2001-2007, SADAHIRO Tomoyuki. Japan. All rights reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

参考資料

Microsoft PRB, Article ID: Q170559

Conversion Problem Between Shift-JIS and Unicode

cp932 to Unicode table

http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT

http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit932.txt

http://www.microsoft.com/globaldev/reference/dbcs/932.htm