2009-10-23 14 views
7

私はすでに次のコードのようなものを使用して、UTF-8エンコードに行毎にファイルの非UTF8エンコードされたコンテンツを変換する方法を知っている:Perlで入力ファイルをUTF-8エンコーディングに変換するにはどうすればよいですか?

# outfile.txt is in GB-2312 encode  
open my $filter,"<",'c:/outfile.txt'; 

while(<$filter>){ 
#convert each line of outfile.txt to UTF-8 encoding 
    $_ = Encode::decode("gb2312", $_); 
...} 

しかし、私はPerlが直接全体を符号化することができると思います

#outfile.txt is in GB-2312 encode 
open my $filter,"<:utf8",'c:/outfile.txt'; 

(Perlが言う "UTF8 "\ XD4" Unicodeにマッピングされていない" のようなもの)

などのUTF-8形式の入力ファイルなので、私が試した何か
open my $filter,"<",'c:/outfile.txt'; 
$filter = Encode::decode("gb2312", $filter); 

(Perlが「未開封ファイルハンドル上のreadline()を言う!)

彼らは動作しません。しかし、入力ファイルをUTF-8エンコードに直接変換する方法はありますか?

更新:物事が思ったほど単純ではないよう

が見えます。私はラウンドアバウトの方法で入力ファイルをUTF-8コードに変換できるようになりました。最初に入力ファイルを開き、その内容をUTF-8にエンコードしてから新しいファイルに出力し、新しいファイルを開いてさらに処理します。これはコードです:

open my $filter,'<:encoding(gb2312)','c:/outfile.txt'; 
open my $filter_new, '+>:utf8', 'c:/outfile_new.txt'; 
print $filter_new $_ while <$filter>; 
while (<$filter_new>){ 
... 
} 

しかし、これはあまりにも多くの仕事で、単に線で$フィルタラインのコンテンツをエンコードよりも、それがさらに厄介です。

+3

質問に警告メッセージが記載されている場合は、質問に警告メッセージを含めてください。 :) –

+0

@ブライアン、提案のおかげで。 – Mike

+1

正確な警告メッセージを使用することをお勧めします:)この警告では、あなたのオープンの結果をチェックする必要があります。 –

答えて

5

私はあなたの質問に誤解していると思います。あなたがしたいことは、非UTF-8エンコーディングでファイルを読み込んだ後、プログラムでUTF-8としてデータを再生することだと思います。それははるかに簡単です。適切なエンコーディングでデータを読み込んだら、Perlは内部的にUTF-8として表現します。だから、あなたがしなければならないことをやってください。

これを書き戻すときは、保存するエンコードを使用してください。ただし、ファイルを使用するためにファイルに戻す必要はありません。


古い答え

PerlのI/O層は、それがすでに適切にエンコードされますと仮定したデータを読み込みます。あなたのエンコーディングを変換するつもりはありません。 utf8をopenに使用するように指示することにより、utf8がすでにutf8であることがわかります。

あなたが表示したのと同じように(自分のI/Oレイヤーを書きたい場合を除き)、Encodeモジュールを使用する必要があります。バイトをUTF-8に変換することも、エンコーディングがわかっている場合は、あるエンコーディングから別のエンコーディングに変換することもできます。すでにエンコーディングが分かっているようですので、from_to()の機能が必要です。

PerlとUnicodeを使い始めたばかりなら、何かをする前にJuerd's Perl Unicode Adviceを実行してください。

+0

@brian、ガイダンスのおかげで。私は、入力ファイルをUTF-8エンコードに直接変換する簡単な方法があるはずだと思っていました。しかし、今は物事がそれほど単純ではないように見えます。私は入力ファイルを最初に開いてからUTF-8にエンコードし、UTF-8エンコードで別のファイルに出力して別のファイルを開くことができます。コードは次のようになります。 open $ my filter、 '<:encoding(gb2312)'、 'c:/outfile.txt'; my $ filter_new、 '+>:utf8'、 'c:/f2.txt'を開きます。 $ filter_new $ _を印刷中に<$filter>; while(<$filter_new>){...} これはあまりにも多くの作業です。 while(<$fh_out>){ – Mike

+0

あまりにも多くの作業のあなたの考えは歪んでいます。手でそれをやってみて、そして戻ってきて、Perlがあなたのためにいかに簡単にそれを作っているか教えてください。今日の子供たちは、彼らがそれをどの程度持っているか分かりません。 :) –

+0

マイクの本能は正しい。あなたは彼が望む変換を直接行うためにレイヤーをスタックすることができます:) – ysth

4

:エンコードレイヤーは、UTF-8を返します。これは、perlの使用に適しています。つまり、複数のバイトであっても、perlは各文字を文字として認識します。データで次に何をするかによって、これで十分でしょう。

しかし、perlがutf8からダウングレードしようとしているデータで何かをしているのなら、perlに(例えば、binmode(STDOUT、 ":utf8")を実行してstdoutへの出力はutf8でなければなりません)、またはperlがutf8をバイナリデータとして扱う必要があります(各バイトを別々に解釈し、utf8文字については何も知らない)。

これを行うには、あなたのオープンに追加の層:以下の出力が同じであることを

open my $foo, "<:encoding(gb2312):bytes", ...; 

注:

perl -we'open my $foo, "<:encoding(gb2312):bytes", "foo"; $bar = <$foo>; print $bar' 
perl -CO -we'open my $foo, "<:encoding(gb2312)", "foo"; $bar = <$foo>; print $bar' 

が、1つの場合には、Perlはデータが読み込まことを知っているが、UTF8(およびその長さ($バー)UTF8文字の数を報告します)で、明示的にSTDOUTはUTF8を受け入れること(-COで)言われるしましたもう一方では、perlはデータについて何も仮定しません(そして、length($ bar)はバイト数を報告します)。そのまま出力します。

関連する問題