1. ホーム
  2. perl

[解決済み] use utf8;を使用すると「印刷時の文字が太い」と言われる

2023-03-12 21:54:11

質問

以下の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を使っています。私は、これがコマンドライン上のワンライナーでなく、ファイル内にある場合、同じ問題があります。

どのように解決するのですか?

がない場合 use utf8 Perlは文字列を1バイト文字の列として解釈します。このように、文字列には4バイトが含まれています。

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

最初の3バイトが文字を構成し、最後の1バイトが改行となります。

の呼び出しは print の呼び出しは、これらの4つの文字をSTDOUTに送ります。コンソールはこれらの文字をどのように表示するかを決定します。コンソールがUTF8を使用するように設定されている場合、これらの3バイトを1文字として解釈し、それが表示されます。

もし 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 (printなど) でデフォルトで表示されます。 この警告を消す最も簡単な方法は この警告を消す最も簡単な方法は、出力に :utf8 レイヤーを追加することです。 を追加することです。例えば、binmode STDOUT, ':utf8'とします。 この警告を消すもう一つの方法は 警告を消すもう一つの方法は、警告を出さない 'utf8' を追加することです; しかし、これはしばしば不正行為に近くなります。 しかし、これは不正行為に近いものです。 一般的には、ファイルハンドルを明示的にエンコーディングでマークすることになっています。 ファイルハンドルをエンコーディングで明示的にマークすることになっています。

他の人が指摘したように、Perlにマルチバイト出力を受け入れるよう指示する必要があります。これを行うには多くの方法があります ( Perl Unicode チュートリアル を参照してください)。最も簡単な方法のひとつは -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は大きく複雑な分野です。これまで見てきたように、多くの単純なプログラムは正しいことを行っているように見えますが、間違った理由のために行われています。プログラムの一部を修正し始めると、多くの場合、修正するまで事態は悪化していきます。 すべて を修正するまで、事態は悪化することがよくあります。