[pod] [xml]

NAME

perlunicode - Perl における Unicode サポート

DESCRIPTION

Important Caveats

(重要な警告)

Uncode サポートは大規模な要求です。 Perl は標準 Unicode や付随する技術的なレポートを一つ残らず 実装しているわけではありませんが、多くの Unicode 機能を サポートしています。

Perl で Unicode を使うことを学びたい人は、多分このリファレンスを読む前に the Perl Unicode tutorial を読んだ方がよいでしょう。

Byte and Character Semantics

(バイトと文字のセマンティクス)

バージョン 5.6 から、Perl は論理的なワイド文字を内部的な文字列の 表現のために使っています。

将来は、Perl レベルの操作はバイトではなく文字に対して働くことになるでしょう。

しかしながら、一時的な互換性の措置として、Perl は プログラムに対するバイトセマンティクスから文字セマンティクスへの 安全な移行パスを提供することを目指します。 入力データが文字であると Perl が曖昧さなく決定できる操作については、 Perl は文字セマンティクスに切り替えます。 ユーザーからの付加的な情報抜きに決定することができない操作については Perl は互換性の観点からバイトセマンティクスを選択します。

この動作は Perl の以前のバージョンとの互換性を維持し、プログラムの 入力が Unicode の文字データのソースであるとマークされていない場合にのみ Perl の操作でバイトセマンティクスを許可します。 そのようなデータは、ファイルハンドル、外部プログラムの呼び出し、 システムから提供される情報(%ENV のような)、ソーステキスト中のリテラルや 定数といったものからくるものです。

bytes プラグマは常に、プラットフォームとは無関係に、特定の レキシカルスコープにおいてバイトセマンティクスを強制します。 bytes を参照してください。

utf8 プラグマは主としてパーサが遭遇するリテラル中の UTF-(8|EBCDIC) の 認識を有効にする互換デバイス(compatibility device)です。 このプラグマは Perl のデフォルトがバイトセマンティクスであるときにのみ 必要であることに注意してください。 文字セマンティクスがデフォルトである場合には、 このプラグマは何もしません。 utf8 を参照してください。

明示的に指定されない限り、Perl の演算子は Unicode データに対しては 文字セマンティクスを用い、非 Unicode データに対しては バイトセマンティクスを用います。 文字セマンティクスの使用の決定はトランスペアレントに行われます。 もし入力データが Unicode ソースから来たもの -- たとえば、 文字エンコーディング層がファイルハンドルに附加されているか リテラルの Unicode 文字列定数がプログラムの中にある -- のであれば 文字セマンティクスが適用されます。 そうでなければ、バイトセマンティクスが有効になります。 bytes プラグマは Unicode データに対してバイトセマンティクスを 強制するときに使うと良いでしょう。

バイトセマンティクスの元での文字列の操作で、Unicode 文字データが 連結された文字列であった場合、新たな文字列は、古い Unicode 文字列が EBCDIC を使っていたとしても、バイト文字列を ISO 8859-1 (Latin-1) として デコードすることで作成されます。 この変換はシステムのネイティブな 8 ビットエンコーディングとは 無関係に行われます。

文字セマンティクスの元では、伝統的にバイトに対して働いていた操作の多くが 文字に対して働きます。 Perl における文字は論理的には 0 から 2**31 までの範囲の数値です。 大きな文字は内部的にはより長いシーケンスにエンコードされる可能性が ありますが、この内部の詳細は Perl プログラムからほとんど隠されています。 詳細は perluniintro を参照してください。

Effects of Character Semantics

(文字セマンティクスの効果)

文字セマンティクスは以下の効果を持っています:

Unicode Character Properties

(Unicode 文字特性)

名前付けされた Unicode の特性、用字、ブロックの範囲は \p{} "matches property" 構造やその否定形の \P{} "doesn't match property" を 使った文字クラスで使うことができます。

たとえば、\p{Lu} は Unicode の "Lu" (Letter, uppercase) 特性を持つ任意の 文字にマッチし、\p{M} は "M" (mark -- アクセントなど) 特性を持つ任意の 文字にマッチします。 ブラケットは一文字の特性では省略することができるので、\p{M}\PM と等価です。 \p{Mirrored}\p{Tibetan} など多くの特性が定義されています。

公式の Unicode 用字およびブロックの名前はスペースとダッシュを セパレータとして使っていますが、便利のため、ダッシュ、スペース、 アンダーバーを使うことができ、また、大小文字の違いは重要ではありません。 しかしながら、以下のネーミングにしたがって、首尾一貫して使うことを お勧めします: Unicode の用字、特性、ブロックの名前 (ブロック名に 適用される付加的なルールについて以下を参照してください) から 空白とダッシュを取り除き、単語の先頭を大文字にし残りを小文字にします。 したがって、Latin-1 SupplementLatin1Supplement となります。

\p{}\P{} の両方で、キャレット(^) を最初のブレースと 特性名の間に置くことによって意味を反転することができます: \p{^Tamil}\P{Tamil} と等価です。

注意: ここでの特性、用字、ブロックは 2006 年 7 月の Unicode 5.0.0 に 従っています。

User-Defined Character Properties

(ユーザ定義文字特性)

あなた自身の文字特性を、"In" または "Is" で始まる名前のサブルーチンを 定義することによって持つことができます。 そのサブルーチンは任意のパッケージで定義することができます。 ユーザー定義特性は正規表現の \p 構造や \P 構造で使うことができます。 もしユーザー定義特性をそれがあるパッケージ以外で使いたいのであれば、 パッケージ名を \p (もしくは \P)のために指定する必要があります。

    # assuming property IsForeign defined in Lang::
    package main;  # property package name required
    if ($txt =~ /\p{Lang::IsForeign}+/) { ... }
    package Lang;  # property package name not required
    if ($txt =~ /\p{IsForeign}+/) { ... }

この効果はコンパイル時のもので、一度定義してしまったら 変更できないことに注意してください。

サブルーチンは、ひとつ以上の改行で区切られた特定の形式の文字列を 返さなければなりません。 各行は以下のいずれかの形式でなければなりません:

例えば、両方の日本語の音節(ひらがなとカタカナ)を対象とする特性を 定義するには、以下のように定義します

    sub InKana {
	return <<END;
    3040\t309F
    30A0\t30FF
    END
    }

ヒアドキュメントの終端マーカーは行の先頭に置かれることを思い出してください。 これで、\p{InKana}\P{InKana} を使うことができます。

すでに存在しているブロック特性名を使うこともできます:

    sub InKana {
	return <<'END';
    +utf8::InHiragana
    +utf8::InKatakana
    END
    }

生のブロック範囲ではなく、割り当てられた文字のみにマッチさせたいと 考えているとしましょう: 言い換えれば、文字以外のものを 取り除きたいということです:

    sub InKana {
	return <<'END';
    +utf8::InHiragana
    +utf8::InKatakana
    -utf8::IsCn
    END
    }

否定は否定クラスを定義するのに便利です。

    sub InNotKana {
	return <<'END';
    !utf8::InHiragana
    -utf8::InKatakana
    +utf8::IsCn
    END
    }

共通集合(intersection)は二つ以上のクラスにマッチする共通の文字を得るのに 便利です。

    sub InFooAndBar {
        return <<'END';
    +main::Foo
    &main::Bar
    END
    }

最初の集合に "&" を使わないということを忘れないでください -- そうしてしまうと空との共通集合を取ってしまいます(結果は空集合です)。

User-Defined Case Mappings

(ユーザ定義の大文字・小文字の対応関係)

同様に、lc()、lcfirst()、uc()、ucfirst() (あるいはその文字列組み込み版)で あなた自身の対応関係を定義することもできます。 原則は ユーザー定義文字特性の場合と似ています: ToLower (lc() と lcfirst()用), ToTitle (ucfirst() の最初の文字用), ToUpper (uc() 用と ucfirst() の 残りの文字用) のような名前のサブルーチンを main パッケージで定義します。

サブルーチンから返される文字列はタブで区切られた 3 つの 16 進数を 必要とします: ソースの範囲の始まり、ソースの範囲の終わり、そして デスティネーション範囲の始まりです。 例を挙げましょう:

    sub ToUpper {
	return <<END;
    0061\t0063\t0041
    END
    }

これは、"a", "b", "c" の文字のみを "A", "B", "C" にマッピングして その他のすべての文字は変更しないという uc() のマッピングを定義しています。

もしソースの範囲に言及することがなければ、つまり、対応関係が単一の 文字から別の単一の文字に変換するものであったならば、ソースの範囲の 終わりは空のままでよいけれども二つのタブは必要です。 例を挙げましょう:

    sub ToLower {
	return <<END;
    0041\t\t0061
    END
    }

"A" を "a" にマッピングしてその他のすべての文字は変更しない lc() の マッピングを定義しています。

(真剣なハッカー専用) デフォルトのマッピングを内省したいのなら、 $Config{privlib}/unicore/To/ というディレクトリにデータを 見つけ出すことができます。 マッピングデータはヒアドキュメントとして返され、utf8::ToSpecFoo$Config{privlib}/unicore/SpecialCasing.txt から派生した特殊な 例外マッピングです。 そのディレクトリで見つけることのできる DigitFold のマッピングは ユーザーがダイレクトにアクセスできず、Unicode::UCD モジュールを使うか 大小文字を無視してマッピングします(Fold マッピングが使われているとき)。

ユーザー定義の大文字・小文字の対応関係に関する最後の注意: これらはスカラが Unicode 文字としてマークされているときにのみ使われます。 古いバイト形式の文字列には影響を及ぼしません。

Character Encodings for Input and Output

(入出力のための文字エンコーディング)

Encode を参照してください。

Unicode Regular Expression Support Level

(Unicode 正規表現対応レベル)

以下に挙げるリストは、現在対応している全ての機能を記述する、 正規表現のための Unicode 対応のリストです。 "Level N" に対する参照とセクション番号は Unicode Technical Standard #18, "Unicode Regular Expressions", version 11, in May 2005 を参照しています。

Unicode Encodings

(Unicode のエンコーディング)

Unicode 文字は抽象的な数値である 符号位置 にアサインされています。 これらの数値を使うために、さまざまなエンコーディングが必要となります。

Security Implications of Unicode

(Unicode のセキュリティへの影響)

Unicode in Perl on EBCDIC

(EBCDIC 上の Perl での Unicode)

EBCDIC プラットフォームでの Unicode の扱い方は未だ実験的です。 このようなプラットフォームでは、この文書やその他での UTF-8 エンコーディングへの言及は、特に ASCII 対 EBCDIC 問題について 議論されている場合でない限りは、Unicode Technical Report 16 で 定義されている UTF-EBCDIC を意味するものとして読むべきです。 utfebcdic プラグマや ":utfebcdic" 層はありません; 代わりに、"utf8" と ":utf8" が、そのプラットフォームの「自然な」 Unicode の 8 ビットエンコーディングを意味するように再利用されています。 この問題に関する更なる議論については perlebcdic を参照してください。

Locales

(ロケール)

通常ロケールの設定と Unicode は互いに影響を及ぼすことはありませんが、 いくつかの例外があります:

When Unicode Does Not Happen

(Unicode ではない場合)

Perl には入出力を Unicode で行うための多数の方法があり、 @ARGV のように Unicode (UTF-8) として解釈できるようなその他の 「エントリポイント」はほとんどない一方、(何らかのエンコーディングで) Unicode が引数として与えられたり結果として返されるべきにも関わらず、 そうなっていない場所も未だ多くあります。

以下に挙げるのはそのようなインターフェースです。 これらすべてが現在の Perl(5.8.3) では単純に引数と戻り値の両方が バイト文字列か、encoding プラグマが使われていれば UTF-8 文字列で あると仮定しています。

このようなケースにおいて、Perl がなぜ Unicode による解決を しないのかの理由の一つは、答えがオペレーティングシステムや ファイルシステムに強く依存しているからです。 たとえば、ファイル名が Unicode で記述できてエンコーディングが 合っていたとしてもそれは移植性のあるコンセプトではないのです。 同様なことが qx や system にも言えます: 「コマンドラインインターフェース」は Unicode をどのように 扱うのでしょうか?

Forcing Unicode in Perl (Or Unforcing Unicode in Perl)

(Unicode を Perl に強制する (あるいは Unicode でないことを Perl に強制する))

ときとして(/When Unicode Does Not Happen を参照)、Perl にバイト列を UTF-8 であるように強制したりその逆を行う場合があるかもしれません。 低レベルの呼び出し utf8::upgrade($bytestring) と utf8::downgrade($utf8string) がその回答です。

しかし、これらを使うときには十分注意しなければなりません: あなたが突然 スカラのような'性質'(nature)を突然変えたりしたら、Perl は簡単に混乱し、 怒り、クラッシュしてしまいます。 utf8::upgrade() を使うときには特に注意が必要です: 任意のランダムな バイト列は正当な UTF-8 ではありません。

Using Unicode in XS

(XS で Unicode を使う)

Perl の Unicode を XS 拡張で取り扱いたいと思うのなら、以下に挙げる API 群が便利かも知れません。 XS レベルでの Unicode に関しての説明は perlguts/"Unicode Support" を、 API の詳細については perlapi を参照してください。

もっと詳しい情報は、perlapi と、Perl のソースコード配布の utf8.c と utf8.h を参照してください。

BUGS

Interaction with Locales

(ロケールとの相互作用)

Unicode データと共にロケールを使うことはおかしな結果を もたらすことになりやすいです。 現在のところ、Perl は文字に 0..255 の範囲の 8 ビットロケールを 割り当てようとしていますが、このテクニックは Unicode に マップしようとしたときに先の範囲の文字を使用するロケールに対して 明らかに正しくありません。 Perl の Unicode サポートはまた、遅くなりがちです。 Unicode といっしょにロケールを使うことはお勧めできません。

Interaction with Extensions

(エクステンションとの相互作用)

Perl がエクステンションとデータをやり取りするとき、そのエクステンションは UTF8 フラグを理解し、また、それに従った振る舞いをすべきです。 エクステンションがこのフラグについて何も知らなければ、そのエクステンションは 正しくないフラグがついたデータを返す可能性があります。

そのため、もし Unicode データを扱おうというのであれば、 Unicode データの 交換に関して何らかの記述があるのなら使うモジュールすべてのドキュメントを 調べてください。 ドキュメントが Unicode に関して何の言及もしていないのなら、最悪のケースを 考慮し、そしてそのモジュールがどのように実装されているかを知るために ソースを見ることになるかもしれません。 完全に Perl で書かれたモジュールは問題を引き起こしません。 他のプログラミング言語で書かれている直接または間接にアクセスするコードに リスクがあるのです。

影響を受けた関数のための、データの劣化(data corruption)を防ぐ単純な 戦略とは、交換するデータのエンコーディングを常に明確にするということです。 エクステンションが取り扱うことができると知っているエンコーディングを 選択してください。 エクステンションに渡す引数を選択したエンコーディングに変換し、 エクステンションから返ってきた結果をそのエンコーディングから 逆方向に変換します。 変換を行ってくれるラッパ関数を書いておいて、 エクステンションが追いついた時に関数を変更できるようにしておきます。

例として、まだ Unicode データを取り扱うようにはできていない、 有名なな Foo::Bar::escape_html について述べましょう。 ラッパ関数は引数を生の UTF-8 に変換し、結果を Perl の内部表現に 逆変換します:

    sub my_escape_html ($) {
      my($what) = shift;
      return unless defined $what;
      Encode::decode_utf8(Foo::Bar::escape_html(Encode::encode_utf8($what)));
    }

エクステンションがデータを変換しないけれども格納したり取り出したりするときに、 ときとして危険な Encode::_utf8_on() 関数以外のものを 使うことがあるかもしれません。 C で書かれていて、データを以下のプロトタイプに従って格納したり 取り出したりする param メソッドを持っている 有名な Foo::Bar エクステンションについて述べてみましょう:

    $self->param($name, $value);            # set a scalar
    $value = $self->param($name);           # retrieve a scalar

どのエンコーディングもまだサポートしていないのなら、 以下のような param メソッドを持った派生クラスを 記述することができるでしょう:

    sub param {
      my($self,$name,$value) = @_;
      utf8::upgrade($name);     # make sure it is UTF-8 encoded
      if (defined $value) {
        utf8::upgrade($value);  # make sure it is UTF-8 encoded
        return $self->SUPER::param($name,$value);
      } else {
        my $ret = $self->SUPER::param($name);
        Encode::_utf8_on($ret); # we know, it is UTF-8 encoded
        return $ret;
      }
    }

一部のエクステンションはデータのエントリ/脱出ポイントでフィルターを 提供しています。 たとえば DB_File::filter_store_keyとその仲間です。 あなた使うエクステンションのドキュメントにあるそのようなフィルターに 注意してください。 それらは Unicode データの変化をより容易にします。

Speed

(速度)

一部の関数は UTF-8 でエンコードされた文字列に対して適用したときにバイト エンコードされた文字列に対するときよりも遅くなります。 文字に対して働く必要のある length()、substr()、index()のような関数のすべてと 正規表現マッチングは、データが バイトエンコードされているときには かなり 早く動作できます。

Perl 5.8.0 ではこの遅さはしばしば目立つものでした。 Perl 5.8.1 では少なくとも一部の操作については、遅さを改善することを 期待するキャッシングスキーム(caching scheme)が導入されました。 一般的には、UTF-8 エンコードされた文字列に対する操作はまだ遅いものです。 たとえば、\p{Nd} のような Unicode の特性(文字クラス)は対応する \d のような単純なものよりも目立って遅い(5 倍から10 倍)ことが 知られています(繰り返しますが、d は 10 の ASCII 文字に対して マッチするのに対して Nd は 268 の Unicode 文字にマッチします)。

Porting code from perl-5.6.X

(perl 5.6.X からコードを移植する)

Perl 5.8 は 5.6 とは異なる Unicode モデルを持っています。 5.6 ではプログラマは、ある与えられたスコープが Unicode データを 取り扱うのと Unicode データだけがそのスコープにあることを宣言するのに utf8 プラグマの使用を要求されていました。 5.6 で動いていたプログラムを持っているのなら、以下に挙げる微調整を施す 必要があるでしょう。 例は 5.6 でも動くように書かれているので、安心して試すことができます。

SEE ALSO

perlunitut, perluniintro, Encode, open, utf8, bytes, perlretut, perlvar/"${^UNICODE}"