92

次の Perl プログラムを実行すると:

perl -e 'use utf8; print "鸡\n";'

次の警告が表示されます。

Wide character in print at -e line 1.

この Perl プログラムを実行すると:

perl -e 'print "鸡\n";'

警告が表示されません。

use utf8Perl スクリプトでは UTF-8 文字を使用する必要があると思いました。これが機能しないのはなぜですか?どうすれば修正できますか? Perl 5.16.2 を使用しています。これがコマンドラインのワンライナーではなくファイルにある場合、同じ問題があります。

4

6 に答える 6

115

Perl を使用しないuse utf8場合、文字列は 1 バイト文字のシーケンスとして解釈されます。これからわか​​るように、文字列には 4 バイトあります。

$ perl -E 'say join ":", map { ord } split //, "鸡\n";'
233:184:161:10

最初の 3 バイトは文字を構成し、最後の 1 バイトは改行です。

への呼び出しは、printこれらの 4 文字を STDOUT に送信します。コンソールは、これらの文字を表示する方法を考え出します。コンソールが UTF8 を使用するように設定されている場合、これらの 3 バイトが単一の文字として解釈され、それが表示されます。

utf8モジュールを追加すると、状況が異なります。この場合、Perl は文字列を 2 文字として解釈します。

$ perl -Mutf8 -E 'say join ":", map { ord } split //, "鸡\n";'
40481:10

デフォルトでは、Perl の IO レイヤーは、シングルバイト文字で動作していると想定しています。したがって、マルチバイト文字を印刷しようとすると、Perl は何かがおかしいと判断し、警告を出します。いつものように、を含めることで、このエラーの詳細な説明を得ることができますuse diagnostics。次のように表示されます。

(S utf8) Perl はワイド文字 (>255) を想定していないときに遭遇しました。この警告は、I/O (印刷など) に対してデフォルトでオンになっています。この警告を抑える最も簡単な方法は、:utf8 レイヤーを出力に追加することです (例: binmode STDOUT, ':utf8')。警告をオフにする別の方法は、警告を追加しない 'utf8' です。しかし、それは多くの場合、不正行為に近いものです。一般に、エンコーディングでファイルハンドルを明示的にマークすることになっています。 open と perlfunc/binmode を参照してください。

他の人が指摘したように、Perl にマルチバイト出力を受け入れるように指示する必要があります。これを行うには多くの方法があります (いくつかの例については、Perl Unicode チュートリアルを参照してください)。最も簡単な方法の 1 つは、-CSコマンド ライン フラグを使用することです。これは、3 つの標準ファイルハンドル (STDIN、STDOUT、および STDERR) に UTF8 を処理するよう指示します。

$ perl -Mutf8 -e 'print "鸡\n";'
Wide character in print at -e line 1.
鸡

$ perl -Mutf8 -CS -e 'print "鸡\n";'
鸡

Unicode は大きく複雑な領域です。これまで見てきたように、多くの単純なプログラムは正しく動作しているように見えますが、その理由は間違っています。プログラムの一部を修正し始めると、すべてのプログラムを修正するまで状況が悪化することがよくあります。

于 2013-03-05T10:56:27.503 に答える
83

ソースuse utf8;コードが UTF-8 を使用してエンコードされていることを Perl に伝えるだけです。テキストをエンコードする方法を Perl に伝える必要があります。

use open ':std', ':encoding(UTF-8)';
于 2013-03-04T20:34:08.783 に答える
19

すべての標準出力を UTF-8 としてエンコードします。

binmode STDOUT, ":utf8";
于 2014-02-17T21:18:33.840 に答える
14

CPAN モジュールを使用すると、「どこでも utf8 を実行するだけ」に近づくことができますutf8::all

perl -Mutf8::all -e 'print "鸡\n";'

印刷できないもの (レイヤーが提供されていない場合に 255 より大きい文字) を受け取ると、UTF-8 を使用してエンコードするつもりであると見なされますprint:encoding問題について警告した後、そうします。

于 2013-03-04T21:25:43.727 に答える
6

あなたはこれを使うことができます、

perl -CS filename.

また、そのエラーを終了します。

于 2015-04-09T10:40:39.863 に答える