NAME

perluniintro - Perl Unicode の手引き

DESCRIPTION

このドキュメントは、Unicode の一般的な考えと、 Perl で Unicode をどのように使うかを書いています。 Unicode のより深い扱いへのリファレンスについては "Further Resources" を 参照してください。

Unicode

Unicode は、世界の全ての書記体系と、それに加えて、他の多くのシンボルを 体系化することを計画している文字集合標準です。

Unicode と ISO/IEC 10646 は、ほとんど全ての現代の文字集合標準を統合し、 全ての商業的に重要な現代の言語を含む 80 以上の書記体系と数百の以上の言語に 対応する組織的標準です。 もっとも大きい中国語、日本語、韓国語、それぞれの辞書の全ての文字もまた、 符号化されています。 この標準は、最終的には、250 の書記体系と、1000 以上の言語のほとんどすべての 文字を網羅する予定です。 Unicode 1.0 は 1991 年 10 月にリリースされ、Unicode 6.0 は 2010 年 10 月に リリースされました。

Unicode の 文字 は、抽象的な存在です。 Unicode の文字は、どんな特定の整数幅にも、特に、C 言語の char にも 束縛されません。 Unicode は、言語中立で、表示中立です: Unicode は、テキストの言語をエンコードしませんし、 一般的にはフォントや他のグラフィカルなレイアウトの詳細を定義しません。 Unicode は、文字と、それらの文字からなるテキストを操作します。

Unicode は、LATIN CAPITAL LETTER AGREEK SMALL LETTER ALPHA のような 文字と、その文字について固有の番号を定義します; この場合はそれぞれ、 0x0041 と 0x03B1 になります。 このような固有の番号は、符号位置 (code point) と呼ばれます。 符号位置は基本的には全ての Unicode 文字の集合の中の文字の位置なので、 Perl では、序数 (ordinal) がしばしば同じ意味として使われます。

Unicode 標準は、符号位置に 16 進記法を使うのを好みます。 0x0041 のような番号に馴染みがなければ、後のセクション、 "Hexadecimal Notation" を覗いて見て下さい。 Unicode 標準は、U+0041 LATIN CAPITAL LETTER A という表記を使って、 16 進法の符号位置と標準的な文字の名前を書きます。

Unicode はまた、「大文字」、「小文字」、「10 進数字」、「句読点: のような、 様々な文字の 特性 (property) を定義します; これらの特性は、文字の名前と 独立です。 更に、様々な文字に対する、大文字化や小文字化や並び替えといった操作が 定義されています。

Unicode 論理 「文字」は、実際には一つ以上の 実際 の「文字」または 符号位置から構成されます。 西洋の言語では、これは (LATIN CAPITAL LETTER A のような)、基底文字 (base character) に続いて、一つ以上の(COMBINING ACUTE ACCENT のような) 修飾字 (modifiers) によってモデル化されています。、 この基底文字と修飾字の並びは、結合文字の並び (combining character sequence) と呼ばれます。 一部の非西洋言語ではより複雑なモデルが必要なので、Unicode は 書記素クラスタ (grapheme cluster) という概念を作成し、後に 拡張書記素クラスタ (extended grapheme cluster) という形に洗練させました。 例えば、ハングル音節文字は一つの論理文字として考えられますが、とても しばしば三つの実際の Unocde 文字から構成されています: 先頭子音に引き続いて内部母音、それに引き続いて末尾子音です。

これらの拡張書記素クラスタを「複数の文字」と呼ぶかどうかは、どのような 視点を取るかによります。 プログラマならば、おそらく、この順番のそれぞれの要素を、 1 つの単位、あるいは「文字」として、見ようとするでしょう。 しかし、ユーザの視点では、おそらくユーザの言語の文脈でみえるような ものなので、並び全体を一つの「文字」として見るでしょう。 この文書では、プログラマの視点を取ります: 一つの「文字」は一つの Unicode 符号位置です。

一部の基底文字と修飾字の組み合わせは、合成済 (precomposed) 文字です。 例えば、LATIN CAPITAL LETTER A に引き続いて COMBINING ACUTE ACCENT の並びのように、等価な単一の文字があります。 これは LATIN CAPITAL LETTER A WITH ACUTE と呼ばれます。 しかし、これらの合成済文字は一部の組み合わせでのみ利用可能で、主に Unicode と(ISO 8859 のような)伝統的な標準との間の往復変換に対応するために あります。 Unicode がするように並びを使うと、より多くの潜在的な書記素クラスタを 表現するためにより少ない基本構築ブロック(符号位置)で済むようになります。 等価な形式の変換に対応するために、様々な 正規化形式 (normalization form) も定義されています。 従って、LATIN CAPITAL LETTER A WITH ACUTE正規化形式 C (Normalization Form Composed) (短縮形 NFC)にあり、 LATIN CAPITAL LETTER A に引き続いて COMBINING ACUTE ACCENT の並びは 正規化形式 D (Normalization Form Decomposed) (NFD) にある同じ文字を 表現します。

レガシーエンコーディングとの後方互換性のために、 "全ての文字に固有の番号" という考えは、少々壊れています: その代わりに、"少なくとも全ての文字に 1 つの番号" があります。 同じ文字が、いくつかのレガシーエンコーディングの中で、違うように 表現されていました。 逆は真ではありません: 符号位置には、文字が割り当てられていないものも あります。 1 番目に、使われているブロック内にもかかわらず、割り当てられていない 符号位置があります。 2 番目に、特別な Unicode のコントロール文字があり、それらは、本物の文字を 表現しません。

Unicode が最初に着想されたとき、世界中の文字は 16 ビットで表現できると 考えられていました; 0x0000 から 0xFFFF までの最大 0x10000 (あるいは 65,536) 文字が必要であるということです。 これは間違っているとすぐに証明され、Unicode 2.0(1996 年 7 月)から、Unicode は 21 ビット(0x10FFFF)まで、 様々に定義されています; Unicode 3.1(2001 年 3 月) では、0xFFFF を超えた 最初の文字が定義されました。 最初の 0x10000 文字は、Plane 0、または、基本多言語面 (Basic Multilingual Plane)(BMP) と呼ばれます。 Unicode 3.1 で、全部で 17(そう、17)の面が定義されました -- ですが、 まだ、定義された全文字のどこにも、まだ近くにありません。

新しい言語がエンコードされると、Unicode は一般的にはその文字のための 連続した未割り当ての符号位置の ブロック を選びます。 今のところ、それらのブロックの符号位置の数は常に 16 で割り切れます。 現在のところ必要ではないブロック中の余地は将来の成長のために 未見割り当てのまま残されます。 しかし、後のリリースで利用可能な余地よりも多い符号位置が必要になり、 超えた文を扱うために、元のブロックと連続していない新しいブロックを どこかに割り当てる必要があることがあります。 従って、「ブロック」が適切な組織化方法ではないことが早く明らかになったので、 用字 (Script) 特性が作られました。 (後に改良された用字特性である Script_Extensions も追加されました。) 溢れたブロックにある符号位置も元のものと同じ用字を持ちます。 用字の考え方は自然言語によりよく一致します: Latin 用字があり、Greek 用字があり、などです; 数学記号のような複数の用字で使われる文字のための Common といった、 人工的な用字もいくつかあります。 用字は普通複数のブロックにわたっています。 用字に関するさらなる情報については、"Scripts" in perlunicode を 参照してください。 ブロックに分割されたものはありますが、それは、ほとんど完全に、 予想外のものです--文字がどのように割り当てられるかは不自然な結果です。 (この段落は導入の目的のために単純化しすぎていることに注意してください。 Unicode は実際には言語をエンコードするのではなく、それらの書記体系--用字--を エンコードします; そしてある用字は多くの言語で使われます。 Unicode は BAGGAGE CLAIM のようなシンボルのような、実際には 言語ではないようなものもエンコードします。)

Unicode の符号位置は、抽象的な数字です。 この抽象的な数字を入出力するために、数字は、何らかの形で エンコード (encode) や シリアライズ (serialise) されなければなりません。 Unicode は、複数の character encoding forms を定義していますが、 その中で、UTF-8 は、もっとも一般的です。 UTF-8 は、可変長のエンコーディングで、Unicode 文字を 1 から 4 バイト。 他のエンコーディングは、UTF-16 と UTF-32 と、それらの大小のエンディアンの 変形(UTF-8 は、バイトオーダーと独立です)を含みます。 ISO/IEC 10646 は、UCS-2 と UCS-4 の encoding forms を定義しています。

エンコーディングについて -- 例えば、surrogatesbyte order marks(BOMs) -- もっと知りたければ perlunicode を 見て下さい。

Perl の Unicode サポート

Perl v5.6.0 から、Perl は、Unicode をネイティブに扱う能力を持っていました。 しかし、重要な Unicode の作業をするためには、Perl v5.8.0 が最初の 推奨できるリリースです。 メンテナンスリリースである 5.6.1 は初期の Unicode 実装の多くの問題を 修正しましたが、例えば、5.6.1 で、Unicode での正規表現はまだ動作しません。 Perl v5.14.0 は、Unicode 対応がいくつかのコツを使うことなく(ほぼ)切れ目なく 統合された最初のリリースです。 (いくつかの例外があります。 1 番目として、quotemeta のいくつかの違いは Perl 5.16.0 から修正されました。 2 番目として、the range operator のいくつかの違いは Perl 5.26.0 から修正されました。 3 番目として、split のいくつかの違いは Perl 5.28.0 から修正されました。 )

この切れ目のない対応を有効にするには、use feature 'unicode_strings' と します(これは use 5.012 またはそれ以上とすると自動的に選択されます)。 feature を参照してください。 (5.14 はまた、多くのバグおよび Unicode 標準からの逸脱を修正しています。)

Perl v5.8.0 以前では、use utf8 の使用は、現在のブロックやファイルの 操作が、Unicode であると明示するのを宣言するために使われました。 このモデルは間違っているか、少なくとも不格好であることがわかりました: 操作に添付するかわりに、"Unicodeness" は、今や、データに持ち込まれています。 Perl v5.8.0 から、唯一残されている、明示的に use utf8 をする必要がある 状況があります: Perl スクリプト自身が UTF-8 でエンコードされていれば、識別子の 名前および、文字の中と正規表現のリテラルに UTF-8 を使うことができます。 これはデフォルトではありません; なぜなら、レガシーな 8-bit データの スクリプトが壊れるからです。 utf8 を参照してください。

Perl の Unicode モデル

Perl は、Perl 5.6 より前での 8 ビットネイティブのバイト列の文字列と、 Unicode 文字の文字列の両方をサポートします。 一般的な方針は、Perl は、可能な限り長く 8 ビットバイト列としてデータを 保とうとします; しかし、Unicode 性が避けられなくなった時点で、 データは透過的に Unicode に昇格されます。 Perl v5.14.0 より前では、昇格は完全に透過的ではありませんでした ("The "Unicode Bug"" in perlunicode を参照してください)し、後方互換性のために、 完全な透過性は use feature 'unicode_strings' とするか(feature 参照) use 5.012 (またはそれ以上) が選択されなければ得られませんでした。

内部的には、Perl は、プラットフォームの 8 ビット文字セット (例えば、Latin-1)は、デフォルトは UTF-8 ですが、Unicode 文字列に エンコードします。 特に、文字列中の、全ての符号位置は、0xFF 以下であれば、 Perl は、ネイティブの 8 ビットの文字セットを使います。 そうでなければ、UTF-8 を使います。

Perl のユーザは普通は、Perl がその内部文字列をたまたま、どのように エンコードするかを、知る必要も、気にする必要もありませんが、Unicode 文字列を PerlIO 層なしに (「デフォルトの」エンコーディングで) ストリームに 出力しようとすると、関係するようになります。 このような場合、内部的に使われている生のバイト列(それぞれの文字列の必要に 応じて、ネイティブの文字セットか、UTF-8)が使われ、それらの文字列に 0x00FF を 超える文字があれば、"Wide character" の警告が出力されます。

例えば、

      perl -e 'print "\x{DF}\n", "\x{0100}\x{DF}\n"'

ネイティブのバイト列と UTF-8 の、まったく役に立たない混合もまた、 同様に警告を出します:

     Wide character in print at ...

UTF-8 を出力するために、:encoding:utf8 出力層を使います。 先頭にこれを追加することで:

      binmode(STDOUT, ":utf8");

このサンプルプログラムが、出力が完全に UTF-8 であることを保証し、 プログラムの警告を削除します。

-C コマンドラインスイッチか、PERL_UNICODE 環境変数のどちらか一方を 使うことで、標準ファイルハンドルと、デフォルトの open() 層と、 @ARGV の UTF-8 化を自動的に有効に出来ます; perlrun-C オプションの文書を 参照してください。

これは、Perl が他のソフトウェアも同じように動作することを 想定するということを意味することに注意してください: Perl が STDIN が UTF-8 であるべきと信じるように主導されていて、 他のコマンドからくる STDIN が UTF-8 でなければ、 Perl はおそらく不正な UTF-8 であると文句を言います。

Unicode と、I/O の結合の特徴もまた、新しい PerlIO の特徴を使うことを 必要とします。 ほとんど全ての Perl5.8 プラットフォームは、PerlIO を使いますが: "perl -V" を実行して、useperlio=define を見れば、PerlIO を 使っているかどうか、わかります。

Unicode と EBCDIC

Perl 5.8.0 で、EBCDIC プラットフォームでの Unicode 対応が追加されました。 この対応は後のリリースで失効していましたが、5.22 に復活しました。 追加の変換が必要になるので、Unicode 対応は実装が若干より複雑になります。 さらなる情報については perlebcdic を参照してください。

EBCDIC プラットフォームでは、内部 Unicode エンコーディング形式は UTF-8 ではなく UTF-EBCDIC です。 この違いは、ASCII 文字はそのまま UTF-8 にエンコードされるという点において "ASCII セーフ" ですが、一方 UTF-EBCDIC は "EBCDIC セーフ" です; 全ての基本文字 (ASCII の等価物 (like "A", "0", "%", など) を 持つ全てのもの) は EBCDIC および UTF-EBCDIC で同じです。 しばしば、文書では "UTF-8" という用語を UTF-EBCDIC を含む意味で用います。 この文書でもそうです。

Unicode の作成

この章は、v5.22 以降の Perl から完全に適用されます。 それ以前のバージョンでの様々な問題は後述する "Earlier releases caveats" 節にあります。

リテラルで Unicode 文字を作るためには、 \N{...} 記法をダブルクォートされた文字列の中で使います。

 my $smiley_from_name = "\N{WHITE SMILING FACE}";
 my $smiley_from_code_point = "\N{U+263a}";

同様に、正規表現の中でも使えます。

 $smiley =~ /\N{WHITE SMILING FACE}/;
 $smiley =~ /\N{U+263a}/;

または、v5.32 から:

 $smiley =~ /\p{Name=WHITE SMILING FACE}/;
 $smiley =~ /\p{Name=whitesmilingface}/;

実行時に:

 use charnames ();
 my $hebrew_alef_from_name
                      = charnames::string_vianame("HEBREW LETTER ALEF");
 my $hebrew_alef_from_code_point = charnames::string_vianame("U+05D0");

当然、ord() は、逆を行います: 文字を符号位置に変えます。

その他の実行時の選択肢もあります。 pack() を使えます:

 my $hebrew_alef_from_code_point = pack("U", 0x05d0);

あるいは chr() も使えますが、一般的な場合では余り便利ではありません:

 $hebrew_alef_from_code_point = chr(utf8::unicode_to_native(0x05d0));
 utf8::upgrade($hebrew_alef_from_code_point);

引数が 0xFF より大きい場合は utf8::unicode_to_native()utf8::upgrade() は不要なので、 前述のものは次のようにも書けます

 $hebrew_alef_from_code_point = chr(0x05d0);

0x5d0 は 255 より大きいからです。

\x{}\o{} はダブルクォート風文字列の中でコンパイル時に 符号位置を指定するのにも使えますが、古い Perl との後方互換性のために、 256 より小さい符号位置に対する chr() と同じ規則が適用されます。

utf8::unicode_to_native() は Perl コードを EBCDIC プラットフォームと 互換性を持たせるために使われます。 もし、あなたのコードを非 ASCII プラットフォームで使おうとする人が いないことが 本当に 確実なら、これを省略できます。 Perl v5.22 から、ASCII プラットフォームでのこれの呼び出しは最適化により 削除されるので、これを追加することによる性能上のペナルティは全くありません。 あるいは単にこれを必要としない他の構文を使うことも出来ます。

これら全ての名前と数字のコードを見つける方法は、"Further Resources" を 参照してください。

初期リリースの問題点

EBCDIC プラットフォームでは、v5.22 より前では、\N{U+...} の使用は 正しく動作しません。

v5.16 より前では、(U+... 符号位置ではなく) 文字名での \N{...} の使用には use charnames :full が必要です。

v5.14 より前では、(U+... 符号位置ではなく) 文字名での \N{...} の使用には バグがあります。

charnames::string_vianame() は v5.14 で導入されました。 これより前では、charnames::vianame() は動作するはずですが、 引数が "U+..." 型式の場合のみです。 実行時 Unicode を文字名で扱うための最良の方法はおそらく次のようなものです:

 use charnames ();
 my $hebrew_alef_from_name
                  = pack("U", charnames::vianame("HEBREW LETTER ALEF"));

Unicode を扱う

Unicode を扱うことは、ほとんどの部分では透過的です: 文字列をいつものように 使うだけです。 index()length()substr() のような関数は Unicode 文字列で 動きます; 正規表現も Unicode 文字列で動きます(perlunicodeperlretut を参照してください)。

Perl は書記素クラスタを別々の文字と考えていることに注意して下さい; 従って、例えば

 print length("\N{LATIN CAPITAL LETTER A}\N{COMBINING ACUTE ACCENT}"),
       "\n";

これは 1 ではなく、2 を表示します。 唯一の例外は、正規表現に拡張書記素クラスタにマッチするために、\X が ある場合です。 (従って正規表現内の \X は両方の例の文字の並び全体にマッチングします。)

しかし、レガシーエンコーディング、I/O、そしてある種の特殊な状況では、 人生はそれほど透過的ではありません:

レガシーエンコーディング

レガシーデータと Unicode とを組み合わせる時は、 レガシーデータを Unicode に昇格しなければなりません。 通常、レガシーデータは ISO 8859-1 (か、必要なら EBCDIC)が仮定されます。

Encode モジュールは多くのエンコーディングを知っており、 それらのエンコーディングの間の変換をするインターフェースを持っています:

    use Encode 'decode';
    $data = decode("iso-8859-3", $data); # convert from legacy

Unicode I/O

通常、Unicode データを書き出すことは、

    print FH $some_string_with_unicode, "\n";

Unicode 文字列を内部的にエンコードするのにたまたまつかわれている、 生のバイト列を生成することです。 Perl の内部エンコーディングは、そのときに、文字列にたまたまある文字と 同じように、システム依存です。 どの文字も、符号位置が 0x100 以上なら、警告がでます。 出力が明示的に、望んでいるエンコーディングにレンダリングされていることを 保証し、警告を避けるために、望んでいるエンコーディングでストリームを open してください。 いくつか例示します:

    open FH, ">:utf8", "file";

    open FH, ">:encoding(ucs2)",      "file";
    open FH, ">:encoding(UTF-8)",     "file";
    open FH, ">:encoding(shift_jis)", "file";

すでに開かれているストリームに関しては、binmode() を使います:

    binmode(STDOUT, ":utf8");

    binmode(STDOUT, ":encoding(ucs2)");
    binmode(STDOUT, ":encoding(UTF-8)");
    binmode(STDOUT, ":encoding(shift_jis)");

エンコーディング名のマッチングはルーズです: 大文字小文字は区別されず、 多くのエンコーディングでは、いくつかの別名があります。 :utf8 層は、常に、きっちりとそのように指定される必要があります; このことは、エンコーディング名のルーズなマッチングの対象では ありません。 また、今のところデータが妥当な UTF-8 であるかどうかを検証せずに受け入れるので、 入力に対しては :utf8 は安全ではないことにも注意してください; 代わりに :encoding(UTF-8) (ハイフンありかなしかどちらか) を使うべきです。

:utf8 層に関しては、PerlIO を参照してください; :encoding() に関しては、Encode::PerlIO を参照してください; Encode モジュールで対応している、多くのエンコーディングに関しては、 Encode::Supported を参照してください。

Unicode かレガシーのエンコーディングどちらかでたまたまエンコードされている ファイルを読み込んでも、Perl の目で、魔法のように、データが Unicode に 変わったりしません。 そうするためには、ファイルを開くときに、適切な層を指定します。

    open(my $fh,'<:encoding(UTF-8)', 'anything');
    my $line_of_unicode = <$fh>;

    open(my $fh,'<:encoding(Big5)', 'anything');
    my $line_of_unicode = <$fh>;

I/O 層は、もっと柔軟に、open プラグマでもまた、指定することが出来ます。 open を参照するか、次の例を見て下さい。

    use open ':encoding(UTF-8)'; # input/output default encoding will be
                                 # UTF-8
    open X, ">file";
    print X chr(0x100), "\n";
    close X;
    open Y, "<file";
    printf "%#x\n", ord(<Y>); # this should print 0x100
    close Y;

open プラグマで、:local 層も使えます:

    BEGIN { $ENV{LC_ALL} = $ENV{LANG} = 'ru_RU.KOI8-R' }
    # the :locale will probe the locale environment variables like
    # LC_ALL
    use open OUT => ':locale'; # russki parusski
    open(O, ">koi8");
    print O chr(0x430); # Unicode CYRILLIC SMALL LETTER A = KOI8-R 0xc1
    close O;
    open(I, "<koi8");
    printf "%#x\n", ord(<I>), "\n"; # this should print 0xc1
    close I;

ストリームからファイルが読まれるときに、特定のエンコーディングから、 データを変換する I/O ストリーム上の透過的な層です。 その結果は常に Unicode です。

open プラグマは、デフォルトの層を設定することで、プラグマの後の 全ての open() 呼び出しに影響します。 あるストリームだけに影響を限定したいなら、open() 呼び出しで明示的な 層を使って下さい。

binmode() を使って、すでに開かれているストリームのエンコーディングを 変えることが出来ます; "binmode" in perlfunc を参照してください。

:locale は、現在のところ open()binmode() では 動きません; open プラグマでのみ動きます。 :utf8:encoding(...) メソッドは、全ての open()binmode()open プラグマで動きます。

似たようなものに、ストリームに書き出すときに、自動的に Unicode を 特定のエンコーディングに変換する、出力ストリームの I/O 層を使うかも 知れません。 例えば、次のようなコードの断片は、(ISO-2022-JP, またの名を JIS として エンコードされている)" text.jis" ファイルの内容を、UTF-8 として エンコードされる "text.utf8" ファイルにコピーします。

    open(my $nihongo, '<:encoding(iso-2022-jp)', 'text.jis');
    open(my $unicode, '>:utf8',                  'text.utf8');
    while (<$nihongo>) { print $unicode $_ }

open() と、open プラグマの両方で使われているエンコーディングの 名前は、フレキシブルな名前でも使えます: koi8-rと、KOI8R は、 両方とも理解されます。

ISO、MIME、IANA、および様々な他の標準化機関が認識している、一般的な エンコーディングが認識されます; より詳細なリストは、 Encode::Supported を参照してください。

read() は、文字を読み、文字の数を返します。 seek()tell() は、sysseek() と同様に バイトカウントに関して操作します。

sysread()syswrite() は文字エンコーディング層を持つ ファイルハンドルに対して使うべきではありません; これは間違った振る舞いをして、 この振る舞いは perl 5.24 から廃止予定です。

デフォルト層がなければ、入力になんの変換もしないのがデフォルトの 振る舞いなので、繰り返しデータをエンコーディングすることで、 ファイルを展開し続けるコードを誤って書きやすいです。

    # BAD CODE WARNING
    open F, "file";
    local $/; ## read in the whole file of 8-bit characters
    $t = <F>;
    close F;
    open F, ">:encoding(UTF-8)", "file";
    print F $t; ## convert to UTF-8 on output
    close F;

このコードを 2 回実行すると、file の内容は、2 回 UTF-8 に エンコードされます。 use open ':encoding(UTF-8)' でバグを避けられ、 もしくは、UTF-8 として入力するために、File を、明示的に開くことです。

注意: :utf8:encoding の機能は、Perl が、ほとんどのシステムで デフォルトである、PerlIO でビルドされている場合にのみ動作します。

Unicode をテキストとして表示する

Unicode を含んでいる Perl のスカラを、単純な ASCII(か、EBCDIC)の テキストとして、表示したいかもしれません。 下のサブルーチンは、引数を変換して、255 より大きい符号位置の Unicode 文字を \x{...} として表示し、(\n のような)制御文字は \x.. として表示します; 残りの文字は、そのまま表示します:

 sub nice_string {
        join("",
        map { $_ > 255                    # if wide character...
              ? sprintf("\\x{%04X}", $_)  # \x{...}
              : chr($_) =~ /[[:cntrl:]]/  # else if control character...
                ? sprintf("\\x%02X", $_)  # \x..
                : quotemeta(chr($_))      # else quoted or as themselves
        } unpack("W*", $_[0]));           # unpack Unicode characters
   }

例えば、

   nice_string("foo\x{100}bar\n")

は、次のような文字列になり:

   'foo\x{0100}bar\x0A'

表示可能になります。

(ここでは \\N{} ではなく \\x{} が使われています; なぜなら おそらくネイティブな値を見たいだろうからです。)

特殊な状況

発展した話題

その他

質問と回答

16 進記法

Unicode 標準は、16 進記法を使うのを好みます。 それは、256 の文字のブロックに Unicode を分割しているのが、 他の表記よりわかりやすいからです。 10 進記法を使うことも出来ますが、16 進記法を使うことを学べば、 Unicode 標準との暮らしが楽になります。 例えば、U+HHHH 表記は、16 進記法を使います。

0x の接頭辞は、16 進の数字を意味しています; 数字は、0-9 および a-f(か、A-F、大文字小文字は問いません)です。 それぞれの 16 進の数字は 4 ビット、1/2 バイトを表します。 print 0x..., "\n" は 16 進数を 10 進で見せます; printf "%x\n", $decimal は 10 進数を 16 進で見せます。 "hex digits" の 16 進の数字があるなら、hex() 関数を使うことが出来ます。

    print 0x0009, "\n";    # 9
    print 0x000a, "\n";    # 10
    print 0x000f, "\n";    # 15
    print 0x0010, "\n";    # 16
    print 0x0011, "\n";    # 17
    print 0x0100, "\n";    # 256

    print 0x0041, "\n";    # 65

    printf "%x\n",  65;    # 41
    printf "%#x\n", 65;    # 0x41

    print hex("41"), "\n"; # 65

更なるリソース

古い Perl での Unicode

Perl 5.8.0 以降にアップグレード出来なくても、まだ、CPAN から利用できる、 Unicode::StringUnicode::Mmap8bUnicode::Map を使って、 いくつかの Unicode 処理ができます。 GNU recode がインストールされているなら、それの Perl フロントエンドである Convert::Recode を文字変換のために使えます。

下記のものは、ISO 8859-1 (Latin-1) バイト列から UTF-8 バイト列に (あるいはその逆に)素早く変換するものです; このコードは古い Perl 5 でも動きます。

    # ISO 8859-1 to UTF-8
    s/([\x80-\xFF])/chr(0xC0|ord($1)>>6).chr(0x80|ord($1)&0x3F)/eg;

    # UTF-8 to ISO 8859-1
    s/([\xC2\xC3])([\x80-\xBF])/chr(ord($1)<<6&0xC0|ord($2)&0x3F)/eg;

SEE ALSO

perlunitut, perlunicode, Encode, open, utf8, bytes, perlretut, perlrun, Unicode::Collate, Unicode::Normalize, Unicode::UCD

謝辞

Thanks to the kind readers of the perl5-porters@perl.org, perl-unicode@perl.org, linux-utf8@nl.linux.org, and unicore@unicode.org mailing lists for their valuable feedback.

著者、著作権、ライセンス

Copyright 2001-2011 Jarkko Hietaniemi <jhi@iki.fi>. Now maintained by Perl 5 Porters.

This document may be distributed under the same terms as Perl itself.