0

単一ファイルのファイルベースのブログである pplog をいじっています。

ファイルコードへの書き込み:

open(FILE, ">$config_postsDatabaseFolder/$i.$config_dbFilesExtension");

my $date = getdate($config_gmt);
print FILE $title.'"'.$content.'"'.$date.'"'.$category.'"'.$i;    # 0: Title, 1: Content, 2: Date, 3: Category, 4: FileName
print 'Your post '. $title.' has been saved. <a href="?page=1">Go to Index</a>';
close FILE;

入力テキスト:

春眠不覺曉,處處聞啼鳥. 夜來風雨聲,花落知多小.

ファイルに保存すると、次のようになります。

春眠不覺�›�,處處聞啼鳥.  夜來風�›�聲,花落知多小.

Eclipse を使用してファイルを編集し、通常のレンダリングを行うことができます。ファイルへの印刷中に問題が発生しました。

基本情報: utf8 を使用しない Strawberry perl 5.12; use utf8; を試してみましたが、効果がありません。

ありがとうございました。

--- 編集 --- コメントありがとうございます。私はコードをたどった:

コードは新しいコンテンツを追加します:

# Blog Add New Entry Page

    my $pass = r('pass');


        #BK 7JUL09 patch from fedekun, fix post with no title that caused zero-byte message...  
        my $title = r('title');
        my $content = '';
        if($config_useHtmlOnEntries == 0)
        {
            $content = bbcode(r('content'));
        }
        else
        {
            $content = basic_r('content');
        }
        my $category = r('category');
        my $isPage = r('isPage');

sub r
{
    escapeHTML(param($_[0]));
}

sub r コマンドを CGI.pm 関数に転送します。

CGI.pmで

sub escapeHTML {
     # hack to work around  earlier hacks
     push @_,$_[0] if @_==1 && $_[0] eq 'CGI';
     my ($self,$toencode,$newlinestoo) = CGI::self_or_default(@_);
     return undef unless defined($toencode);
     $toencode =~ s{&}{&amp;}gso;
     $toencode =~ s{<}{&lt;}gso;
     $toencode =~ s{>}{&gt;}gso;
     if ($DTD_PUBLIC_IDENTIFIER =~ /[^X]HTML 3\.2/i) {
     # $quot; was accidentally omitted from the HTML 3.2 DTD -- see
     # <http://validator.w3.org/docs/errors.html#bad-entity> /
     # <http://lists.w3.org/Archives/Public/www-html/1997Mar/0003.html>.
        $toencode =~ s{"}{&#34;}gso;
     }
     else {
        $toencode =~ s{"}{&quot;}gso;
     }

    # Handle bug in some browsers with Latin charsets
    if ($self->{'.charset'} 
            && (uc($self->{'.charset'}) eq 'ISO-8859-1'    # This line cause trouble. it treats Chinese chars as ISO-8859-1
            || uc($self->{'.charset'}) eq 'WINDOWS-1252')) {
                $toencode =~ s{'}{&#39;}gso;
                $toencode =~ s{\x8b}{&#8249;}gso;
                $toencode =~ s{\x9b}{&#8250;}gso;
        if (defined $newlinestoo && $newlinestoo) {
            $toencode =~ s{\012}{&#10;}gso;
            $toencode =~ s{\015}{&#13;}gso;
        }
    }
    return $toencode;
}

さらに問題を追跡すると、ブラウザのデフォルトが iso-8859-1 であることがわかり、手動で utf-8 に設定しても、文字列が iso-8859-1 としてサーバーに返されます。

ついに、

print header(-charset => qw(utf-8)), '<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />

-charset => qw(utf-8) パラメーターをヘッダーに追加します。漢詩はやはり漢詩です。

Schwern のコメントに感謝します。問題を突き止めてリーソンを学ぶきっかけになりました。

4

3 に答える 3

2

Perl で utf8 を実際に動作させるには、多くの個々の機能をオンにする必要があります。 use utf8コードをutf8(文字列、変数、正規表現...)にするだけで、ファイルハンドルを個別に行う必要があります。

複雑ですが、最も簡単なのはutf8::allを使用することです。これにより、utf8 がコード、ファイル、@ARGV、STDIN、STDOUT、および STDERR のデフォルトになります。utf8 サポートは Perl で常に改善されており、utf8::all は利用可能になり次第追加します。

于 2011-06-29T18:54:43.203 に答える
0

コードがその出力をどのように生成できるかわかりません。たとえば、引用符がありません。もちろん、これはあなたのファイルと私がページを見ている間のどこかでの「破損」が原因である可能性があります。SOは、破損したUTF-8をフィルタリングする場合があります。将来的には16進ダンプを提供することをお勧めします!

とにかく、PerlでUTF-8出力を機能させるには、いくつかのアプローチがあります。

  1. 文字データを操作します。つまり、変数にUnicodeが含まれていることをPerlに知らせます。これはおそらく最良の方法です。それが正しいことを確認しutf8::is_utf8($var)ます(これは必要ありませんし、そうすべきでは use utf8ありません)。Encodeそうでない場合は、モジュールの関数を調べて、decodePerlにUnicodeを認識させます。Perlがデータが文字であることを認識すると、その印刷は警告を出します(これは有効になっていますか?)。修正するには、ファイルで:utf8または:encoding(utf8)レイヤーを有効にします(後者のバージョンではエラーチェックが提供されます)。これは、open(open FILE, '>:utf8', "$fname")で行うか、binmode(binmode FILE, ':utf8')で有効にすることができます。他のエンコーディングも使用できることに注意してください。encodingおよびPerlIO::encodingドキュメントを参照してください。

  2. Unicodeを不透明なバイナリデータとして扱います。utf8::is_utf8($var)falseである必要があります。文字列を操作するときは、細心の注意を払う必要があります。たとえば、UTF-16-BEを使用している場合、これは悪い考えです。print "$data\n"実際にはが必要だからですprint $data\0\n"。UTF-8にはこれらの問題はほとんどありませんが、注意する必要があります。

perluniintro、perlunitut、perlunicode、およびperlunifaqのマンページ/ポッドを読むことをお勧めします。

また、use utf8;スクリプトがUTF-8で記述されていることをPerlに通知するだけです。その効果は非常に限られています。そのポッドドキュメントを参照してください。

于 2011-06-29T16:23:32.890 に答える
0

実際に実行されているコードを表示していません。入力として提供されたテキストは、Cygwin の 5.10.1 と Windows の 5.12.3 の両方で正常に処理されました。したがって、コードにバグがあると思われます。自己完結型の短いテスト ケースを作成して、問題を絞り込んでみてください。

于 2011-06-29T19:24:04.187 に答える