次のPerlプログラムを実行した場合:
Perl -e 'use utf8; print "鸡\n";'
私はこの警告を受け取ります:
Wide character in print at -e line 1.
このPerlプログラムを実行する場合:
Perl -e 'print "鸡\n";'
警告は表示されません。
use utf8
は、PerlスクリプトでUTF-8文字を使用するために必要でした。なぜこれが機能しないのですか、どうすれば修正できますか? Perl 5.16.2を使用しています。これがコマンドラインの1つのライナーではなくファイルにある場合、同じ問題が発生します。
use utf8
がない場合、Perlは文字列を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 Tutorial を参照してください)。最も簡単な方法の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は大きく複雑な領域です。あなたが見てきたように、多くの単純なプログラムは正しいことをしているように見えますが、それは間違った理由のためです。プログラムの一部を修正し始めると、多くの場合、プログラムのallを修正するまで事態は悪化します。
すべて use utf8;
は、ソースコードがUTF-8を使用してエンコードされていることをPerlに伝えます。テキストのエンコード方法をPerlに指示する必要があります。
use open ':std', ':encoding(UTF-8)';
すべての標準出力をUTF-8としてエンコードします。
binmode STDOUT, ":utf8";
CPANモジュール utf8::all
。
Perl -Mutf8::all -e 'print "鸡\n";'
print
が印刷できないものを受け取ったとき(:encoding
レイヤーが提供されます)、UTF-8を使用してエンコードすることを想定しています。問題について警告した後、そうします。
これを使用できます
Perl -CS filename.
また、そのエラーも終了します。
スペイン語では、次の使用を開始するときにこのエラーを見つけることができます。
use utf8;
エディターのエンコードは別のエンコードです。そのため、エディターに表示されるのは、Perlが行うことではありません。このエラーを解決するには、エディターのエンコードをnicode/UTF-8に変更するだけです。