5.24.1

名前

perlunitut - Perl Unicode Tutorial

perlunitut - Perl における Unicode のチュートリアル

説明

The days of just flinging strings around are over. It's well established that modern programs need to be capable of communicating funny accented letters, and things like euro symbols. This means that programmers need new habits. It's easy to program Unicode capable software, but it does require discipline to do it right.

文字列を単に放り出す日々は終わりました。 最近のプログラムでは変わったアクセントのついた文字や、ユーロのマークの ようなものを通信出来る必要があることが確立しています。 これは、プログラマは新しい意味が必要であることを意味しています。 Unicode 対応ソフトウェアをプログラムするのは簡単ですが、それを正しく行うには 訓練が必要です。

There's a lot to know about character sets, and text encodings. It's probably best to spend a full day learning all this, but the basics can be learned in minutes.

文字集合とテキストエンコーディングに関しては学ぶべきことがたくさんあります。 おそらくこれら全てを学ぶのに丸一日を使うのが最良ですが、基本は数分で 学べます。

These are not the very basics, though. It is assumed that you already know the difference between bytes and characters, and realise (and accept!) that there are many different character sets and encodings, and that your program has to be explicit about them. Recommended reading is "The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)" by Joel Spolsky, at http://joelonsoftware.com/articles/Unicode.html.

しかし、これらは超基本ではありません。 あなたがすでにバイトと文字の違いを知っていて、様々な文字集合と エンコーディングがあることを自覚していて(さらに受け入れていて!)、 あなたのプログラムがこれらを明示的にする必要がある、と仮定しています。 お勧めの読み物は Joel Spolsky による "The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)" http://joelonsoftware.com/articles/Unicode.html です。

This tutorial speaks in rather absolute terms, and provides only a limited view of the wealth of character string related features that Perl has to offer. For most projects, this information will probably suffice.

このチュートリアルはどちらかといえば独立した用語を使っていますし、Perl が 提供している豊富な文字列に関する機能のうち限定された見方のみを扱っています。 ほとんどのプロジェクトにとっては、おそらくこの情報で十分です。

定義

It's important to set a few things straight first. This is the most important part of this tutorial. This view may conflict with other information that you may have found on the web, but that's mostly because many sources are wrong.

まず、いくつかのことをはっきりさせることが重要です。 これはこのチュートリアルで最も重要な部分です。 この考え方はあなたが web で見つけたその他の情報と矛盾するかもしれませんが、 ほとんどの場合、それは web で見つけた情報の方が間違っているためです。

You may have to re-read this entire section a few times...

このセクション全体を何回か読み直す必要があるかもしれません…

Unicode

Unicode is a character set with room for lots of characters. The ordinal value of a character is called a code point. (But in practice, the distinction between code point and character is blurred, so the terms often are used interchangeably.)

Unicode は大量の文字を表現できる文字集合です。 文字の序数は 符号位置 と呼ばれます。 (しかし実際には、符号位置と文字との区別はあいまいなので、この用語はしばしば 同義語として使われます。)

There are many, many code points, but computers work with bytes, and a byte has room for only 256 values. Unicode has many more characters than that, so you need a method to make these accessible.

符号位置は本当に大量にありますが、コンピュータはバイト単位で 動いていて、バイトは 256 種類の値のみを持ちます。 Unicode はもっとたくさんの文字を持っているので、これらにアクセスできるような 手法が必要です。

Unicode is encoded using several competing encodings, of which UTF-8 is the most used. In a Unicode encoding, multiple subsequent bytes can be used to store a single code point, or simply: character.

Unicode はいくつかの競合するエンコーディングを使ってエンコードされていて、 UTF-8 がもっともよく使われています。 Unicode のエンコーディングでは、複数の引き続くバイト列を一つの符号位置 (あるいは単純に「文字」)を保管するのに使います。

UTF-8

UTF-8 is a Unicode encoding. Many people think that Unicode and UTF-8 are the same thing, but they're not. There are more Unicode encodings, but much of the world has standardized on UTF-8.

UTF-8 は Unicode のエンコーディングです。 多くの人々は Unicode と UTF-8 は同じだと考えていますが、違います。 Unicode のエンコーディングには他にもありますが、世界のほとんどでは標準として UTF-8 が使われています。

UTF-8 treats the first 128 codepoints, 0..127, the same as ASCII. They take only one byte per character. All other characters are encoded as two to four bytes using a complex scheme. Fortunately, Perl handles this for us, so we don't have to worry about this.

UTF-8 は最初の 128 の符号位置(0..127) を ASCII と同様に扱います。 文字毎に 1 バイトしかかかりません。 その他の文字は、複雑な仕組みを使って 2 から 4 バイトを使います。 幸い、Perl がその作業をするので、私たちがそれについて心配する必要は ありません。

テキスト文字列(文字の文字列)

Text strings, or character strings are made of characters. Bytes are irrelevant here, and so are encodings. Each character is just that: the character.

テキスト文字列、または 文字の文字列 は文字からなります。 バイト列はここでは無意味で、エンコーディングも無意味です。 各文字は単に: 文字です。

On a text string, you would do things like:

テキスト文字列では、以下のようにします:

    $text =~ s/foo/bar/;
    if ($string =~ /^\d+$/) { ... }
    $text = ucfirst $text;
    my $character_count = length $text;

The value of a character (ord, chr) is the corresponding Unicode code point.

文字の値 (ord, chr) は対応する Unicode 符号位置です。

バイナリ文字列(バイト文字列)

Binary strings, or byte strings are made of bytes. Here, you don't have characters, just bytes. All communication with the outside world (anything outside of your current Perl process) is done in binary.

バイナリ文字列、または バイト文字列 はバイト列からなります。 ここでは、文字はなく、単にバイトだけがあります。 外側の世界(現在の Perl プロセスの外側のあらゆるもの) との通信はバイナリで 行われます。

On a binary string, you would do things like:

バイナリ文字列では、以下のようにします:

    my (@length_content) = unpack "(V/a)*", $binary;
    $binary =~ s/\x00\x0F/\xFF\xF0/;  # for the brave :)
    print {$fh} $binary;
    my $byte_count = length $binary;

エンコード

Encoding (as a verb) is the conversion from text to binary. To encode, you have to supply the target encoding, for example iso-8859-1 or UTF-8. Some encodings, like the iso-8859 ("latin") range, do not support the full Unicode standard; characters that can't be represented are lost in the conversion.

(動詞としての) エンコードテキスト から バイナリ への変換です。 エンコードするには、iso-8859-1UTF-8 のような、エンコード先の エンコーディングが必要です。 iso-8859 ("latin") のような一部のエンコーディングは、Unicode 標準に 完全に対応していません; 表現できない文字は変換時に失われます。

デコード

Decoding is the conversion from binary to text. To decode, you have to know what encoding was used during the encoding phase. And most of all, it must be something decodable. It doesn't make much sense to decode a PNG image into a text string.

デコードバイナリ から テキスト への変換です。 デコードするには、エンコード時に使われたエンコーディングが何かを知っている 必要があります。 そしてそもそも、それはデコード可能でなければなりません。 PNG イメージをテキスト文字列にデコードしてもほとんど意味はないです。

内部形式

Perl has an internal format, an encoding that it uses to encode text strings so it can store them in memory. All text strings are in this internal format. In fact, text strings are never in any other format!

Perl には 内部形式 と呼ばれる、テキスト文字列をメモリに格納できるように エンコードを行うために使うエンコーディングがあります。 全てのテキスト文字列はこの内部形式になります。 実際、テキスト文字列が他の形式になることは決してないのです!

You shouldn't worry about what this format is, because conversion is automatically done when you decode or encode.

この形式がどのようなものであるかを気にする必要はないはずです; なぜなら 変換はデコードやエンコードの際に自動的に行われるからです。

新しいツールキット

Add to your standard heading the following line:

あなたの標準ヘッダに以下の行を追加します:

    use Encode qw(encode decode);

Or, if you're lazy, just:

あるいは、あなたが怠け者なら、単に以下のようにします:

    use Encode;

I/O の流れ(実際の 5 分間チュートリアル)

The typical input/output flow of a program is:

典型的なプログラムの入出力の流れは以下のものです:

    1. Receive and decode
    2. Process
    3. Encode and output
    1. 受信してデコードする
    2. 処理する
    3. エンコードして出力する

If your input is binary, and is supposed to remain binary, you shouldn't decode it to a text string, of course. But in all other cases, you should decode it.

もし入力がバイナリで、バイナリのままにしておく必要があるなら、これを テキスト文字列にデコードするべきではありません。 しかし、それ以外の全ての場合では、デコードするべきです。

Decoding can't happen reliably if you don't know how the data was encoded. If you get to choose, it's a good idea to standardize on UTF-8.

もしデータがどのようにエンコードされたか分からないなら、デコードには 信頼性がありません。 もしあなたが選択するのなら、UTF-8 に標準化するのはいい考えです。

    my $foo   = decode('UTF-8', get 'http://example.com/');
    my $bar   = decode('ISO-8859-1', readline STDIN);
    my $xyzzy = decode('Windows-1251', $cgi->param('foo'));

Processing happens as you knew before. The only difference is that you're now using characters instead of bytes. That's very useful if you use things like substr, or length.

処理は今まで通りに行います。 唯一の違いは、バイトではなく文字を使うことです。 これは substrlength のようなものを使うときにとても便利です。

It's important to realize that there are no bytes in a text string. Of course, Perl has its internal encoding to store the string in memory, but ignore that. If you have to do anything with the number of bytes, it's probably best to move that part to step 3, just after you've encoded the string. Then you know exactly how many bytes it will be in the destination string.

テキスト文字列にはバイト列はないということを自覚することは重要です。 もちろん、Perl は文字列をメモリに保管するために内部形式を使いますが、 これは無視してください。 もしバイト数を扱うような何かをする必要があるなら、おそらくその部分を ステップ 3 の、文字列をエンコードした直後に移すのが最良です。 そこで目的の文字列が何バイトになるのかが正確に分かります。

The syntax for encoding text strings to binary strings is as simple as decoding:

テキスト文字列をバイナリ文字列にするための文法はデコード時と同じぐらい 単純です:

    $body = encode('UTF-8', $body);

If you needed to know the length of the string in bytes, now's the perfect time for that. Because $body is now a byte string, length will report the number of bytes, instead of the number of characters. The number of characters is no longer known, because characters only exist in text strings.

もし文字列のバイト数が必要なら、今がそれをする最良のタイミングです。 なぜなら $body はバイト文字列なので、length は文字数ではなく、 バイト数を返します。 文字というものはテキスト文字列でのみ存在するので、もはや文字数というものは わからなくなっています。

    my $byte_count = length $body;

And if the protocol you're using supports a way of letting the recipient know which character encoding you used, please help the receiving end by using that feature! For example, E-mail and HTTP support MIME headers, so you can use the Content-Type header. They can also have Content-Length to indicate the number of bytes, which is always a good idea to supply if the number is known.

そしてもしあなたの使っているプロトコルが、あなたが使ったエンコーディングを 相手に伝える方法に対応しているなら、その機能を使って受信側を助けてあげて ください! 例えば、E-mail と HTTP は MIME ヘッダに対応しているので、 Content-Type ヘッダが使えます。 バイト 数を示すための Content-Length もあるので、もしバイト数が わかっているなら、これをつけるのは常に良い考えです。

    "Content-Type: text/plain; charset=UTF-8",
    "Content-Length: $byte_count"

まとめ

Decode everything you receive, encode everything you send out. (If it's text data.)

受け取ったもの全てを decode して、送り出すもの全てを encode しましょう。 (扱っているのがテキストデータなら。)

Q and A (or FAQ)

After reading this document, you ought to read perlunifaq too, then perluniintro.

この文書を読んだ後、perlunifaq と、それから perluniintro も 読むべきです。

謝辞

Thanks to Johan Vromans from Squirrel Consultancy. His UTF-8 rants during the Amsterdam Perl Mongers meetings got me interested and determined to find out how to use character encodings in Perl in ways that don't break easily.

Thanks to Gerard Goossen from TTY. His presentation "UTF-8 in the wild" (Dutch Perl Workshop 2006) inspired me to publish my thoughts and write this tutorial.

Thanks to the people who asked about this kind of stuff in several Perl IRC channels, and have constantly reminded me that a simpler explanation was needed.

Thanks to the people who reviewed this document for me, before it went public. They are: Benjamin Smith, Jan-Pieter Cornet, Johan Vromans, Lukas Mai, Nathan Gray.

著者

Juerd Waalboer <#####@juerd.nl>

SEE ALSO

perlunifaq, perlunicode, perluniintro, Encode