2009-03-09 10 views
92

"utf8"プラグマを使用してPerlスクリプトを作成しようとしていますが、予期しない結果が発生しています。私はMac OS X 10.5(Leopard)を使用しています。私はTextMateで編集中です。私のエディタとオペレーティングシステムの設定はすべて、utf-8形式でファイルを書き込むようにデフォルト設定されています。PerlからUTF-8を出力するにはどうしたらいいですか?

しかし、テキストファイルに次のように入力して ".pl"として保存して実行すると、ASCII以外の文字の代わりにフレンドリーな "疑問符付きのひし形"が表示されます。

#!/usr/bin/env perl -w 

use strict; 
use utf8; 

my $str = 'Çirçös'; 
print("$str\n"); 

私は間違っていると思いますか?私は出力で 'Çirçös'を得ることを期待するが、代わりに ' irs'を得る。

+1

たぶん、そのプログラムではない..私は、私は(私はそれを印刷し、データベースでUTF8を決して入れないしてきた)これについて知らなかった出力 – n00ki3

答えて

141

use utf8; Unicodeを有効にしない出力 - プログラムにUnicodeを入力することができます。 print()の文の前にプログラムに追加してください。

binmode(STDOUT, ":utf8"); 

これが役立つかどうかを確認してください。これにより、通常のASCIIではなく、UTF-8で出力されるSTDOUTになります。

+0

を行い、そのシェルのオーデルあなたのエディタだと思います。 +1。 –

+0

それはうまくいった、クリス。ありがとうございました! –

+1

ようこそ。別の正解も参照してください:http://stackoverflow.com/questions/627661/writing-perl-code-in-utf8/627975#627975そして、TMTOWTDIを覚えておいてください。そして@Paul - ファイルにUTF-8を書いているなら、おそらくそのファイルハンドルにbinmode()を使用して "適切な" UTF-8にするべきですが、それが動作すれば... –

-2

出力をテキストファイルにリダイレクトして、エディタで試してみてください。そこに細かいことが表示されたら、端末が故障しています。

+0

いいえ、Leopard端末ではデフォルトで$ LANGが "en_US.UTF-8"に設定されています。これはデフォルトで(後方互換性のために)Perlは128-255の文字を出力しますか? Unicodeではなく、特に指定しない限り、Unicodeではなく。 –

+0

また、一部のエディタ(vimなど)は、ファイルがUTF-8であるかどうかを自動的に検出し、それがどのエンコーディングであっても正しく表示しようとします。エディタでファイルを開くことは信頼できるテストではありません。 (実際にはかなりの数のエディタが実際には障害のある端末で動作します)。また、文字通り、OPの質問に誤って答えます。 –

-3

があなたのシェルで実行します。 の$ ENVを| grepをLANG

これはおそらく、あなたのシェルがUTF-8ロケールを使用していないことが表示されます。

+0

実際、utf-8に設定されていました。問題は、binmodeをutf-8に設定せずにSTDOUTに出力していたことです。 –

+2

これは直交関係になります。 エミュレータがそれを解釈する方法を心配する前に、 の正しいデータを出力するPerlスクリプトが必要です。 – jrockway

75

open pragmaを使用できます。

たとえば、以下STDOUT、STDIN & STDERRをUTF-8を使用するように設定します....

use open qw/:std :utf8/; 
+1

また良いです。私は+1するだろうが、私は今日の投票から外れている。 –

+1

ところで...私はあなたに+1を与えました。私はbinmode(STDOUT、 ':utf8')はおそらくこの状況でより正しいと思います。 "オープンを使用する"他の良い用途がありますが、私はそれが単にSTDOUTをエンコードするように設定する方法を見つけることができないのですか? – draegtun

57

TMTOWTDI、最高のは、あなたがどのように動作するか合う方法を選択しました。私は環境メソッドを使用するので、私はそれについて考える必要はありません。

perl -CSDL -le 'print "\x{1815}"'; 

又はbinmode有する:

binmode(STDOUT, ":utf8");   #treat as if it is UTF-8 
binmode(STDIN, ":encoding(utf8)"); #actually check if it is UTF-8 

又はPerlIO有する:

export PERL_UNICODE=SDL 

environment

open my $fh, ">:utf8", $filename 
    or die "could not open $filename: $!\n"; 

open my $fh, "<:encoding(utf-8)", $filename 
    or die "could not open $filename: $!\n"; 

またはopen pragmaと:

use open ":encoding(utf8)"; 
use open IN => ":encoding(utf8)", OUT => ":utf8"; 
+1

'-CSDL'は' binmode'だけでは動作しませんでした。総合的な答えは – beerbajay

+1

+1です。 'SDL'は' -C'と 'PERL_UNICODE'の両方で暗示されています。 'use open ':locale''プラグマは' -C'と 'export PER_UNICODE ='のスクリプトに相当するため、言及する価値があります。環境のロケールがUTF8ベースであると仮定した場合、これらの3つのうちのどれでも、すべての入出力ストリーム(ファイルまたはstdin/stdout/stderr)のUTF8サポートが提供されます。最後に、_source_コードをUTF8として扱うには、 'use utf8;'プラグマを使用します。 – mklement0

0

おかげで、最終的にはUTF8を入れないように::エンコードをすべてのコード上で解決策を得ました。 は合成と書き込みのような、他のケースのための完全でUTF8のファイルを読み込み、また

use utf8; 
use open ':encoding(utf8)'; 
binmode(STDOUT, ":utf8"); 

open(FH, ">test.txt"); 
print FH "something éá"; 

use YAML qw(LoadFile Dump); 
my $PUBS = LoadFile("cache.yaml"); 
my $f = "2917"; 
my $ref = $PUBS->{$f}; 
print "$f \"".$ref->{name}."\" ". $ref->{primary_uri}." "; 

どこキャッシュUTF8でYAMLファイルのLoadFileがで動作します。yamlは:

--- 
2917: 
    id: 2917 
    name: Semanário 
    primary_uri: 2917.xml 
1

あなたのコードの中の文字列はutf-8です。 Why does modern Perl avoid UTF-8 by default?を参照してください。したがって、PERL_UNICODE=SDALだけでなく、PERL5OPT=-Mutf8も設定してください。

関連する問題