1

私は、utf8 txt ファイルを受け取り、そのコンテンツを処理する Perl/CGI のアプリケーションを持っています。

何らかの理由で (Perl はファイルを 4096 バイトのバッファーに分割し、最初のバッファーのみにバイト オーダー マークがあると思います)、Perl はファイルの内容を 4096 バイト以降で Unicode として解釈します。

ファイルの途中 (4k の各ブロックに少なくとも 1 つ) にいくつかの en ダッシュ ("–") を広げると、おそらく Unicode には en ダッシュがないため、プログラムはそれを utf8 として認識します。

HTML ページから txt を受け取り、次のようにスカラー変数に送信しています。

while(my $l = <$fh>){
    $text .= $l;
}

ファイルの各行を en ダッシュで連結して、utf8 を強制しようとしました。

while(my $l = <$fh>){
    $text .= "–".$l;
}

しかし、私はこのエラーが発生します:

Wide character in print at (eval 12) line 94.

誰にもヒントがありますか?ありがとうございます!

4

2 に答える 2

3

Perl は Unicode コードポイントで操作できますが、すべての I/O はバイトで行われます。高いコード ポイントを持つ文字列を通常のファイル ハンドルに出力すると、「ワイド文字が出力されます」という警告が表示されます。

すべての入力データをデコードし、すべての出力をエンコードする必要があります。これを行う最善の方法は、PerlIO レイヤーを使用することです。でレイヤーを追加できますbinmode。例えば:

use utf8; # This source file is encoded in UTF-8.
          # Else, the literal "–" would be seen as multiple bytes, not one single character.

binmode STDOUT, ":uft8"; # encode all strings (that get printed to STDOUT)
                         # to the binary UTF-8 representation
print "–\n"; # EN DASH – works.

ファイルを開くときに、オープン モードで PerlIO レイヤーを追加できます。

open my $fh "<:utf8", $filename or die ...;

これにより、バイナリ入力が透過的にコードポイントに変換されます。

バイナリ UTF-8 を含むバイト文字列を適切にデコードされた文字列と連結しないでください。結果は無効なデータになる可能性が高くなります。もちろん、すべての入力をデコードする場合、このような問題は発生しません。

Perl が入力をバッファリングする方法は、プログラムに影響を与えるべきではありません。あなたはそれを誤診している可能性があります。Perl は、入力ファイルの BOM によるエンコーディング検出を行いません。

Web プログラミングのコンテキストでは、出力を UTF-8 としてエンコードすることをお勧めしますが、必ずcharset応答ヘッダーにもプロパティを設定してください。

Content-Type: text/html; charset=UTF-8

HTML ドキュメントでは、これを で繰り返す必要があり<meta charset="UTF-8">ます。

于 2013-09-08T01:14:10.127 に答える
0

試す:

use Encode qw(encode);

$text = join '', <$fh>;

$text = encode("utf8", $text);
于 2013-10-22T08:41:08.680 に答える