我有以下Perl代码,其中我打开标量变量的句柄并向其写入一些utf8文本:
use warnings;
use strict;
use 5.010;
use utf8;
use open qw( :std :encoding(utf8) );
my $output;
open my $oh, ">", \$output;
say $oh "Žluťoučký kůň.";
close $oh;
say "Žluťoučký kůň.";
print $output;
当我运行它时,我得到以下输出:
Žluťoučký kůň.
ŽluÅ¥ouÄký kůÅ.
(没有任何警告或错误)。因此,显然,通过句柄将utf8字符串写入变量在此处无法正常工作,因为字符串似乎是双重编码的。我尝试使用>:raw
,>:bytes
,>:encoding(ascii)
打开$哦,但没有一个帮助。
我可能会做一些愚蠢的事情,但我无法弄清楚如何解决这个问题。有什么想法吗?
答案 0 :(得分:7)
首先,:encoding(utf8)
应为:encoding(utf-8)
。
UTF-8
是众所周知的编码标准。utf8
是UTF-8的Perl特定扩展。(编码名称不区分大小写。)
use open qw( :std :encoding(utf8) );
有两个影响:
:encoding(utf8)
添加到STDIN
,STDOUT
和STDERR
。open
的词汇范围中use
的默认图层设置为:encoding(utf8)
。所以,
use utf8;
use open qw( :std :encoding(UTF-8) );
# String of decoded text aka string of Unicode Code Points, thanks to `use utf8`.
my $text_ucp = "Žluťoučký kůň.";
# $output will contain text encoded using UTF-8 thanks to `use open`.
open my $oh, ">", \my $text_utf8;
say $oh $text_ucp;
close $oh;
# ok. Will encode the decoded text using UTF-8 thanks to `use open`.
say $text_ucp;
# XXX. Will encode the already-encoded text using UTF-8 thanks to `use open`.
print $text_utf8;
您试图覆盖use open
的第二个效果来获取Unicode代码点文件,但这是徒劳的,因为文件只能包含字节。如果您尝试在文件中存储除字节之外的其他内容,则必须进行某种编码或失败。
使用它,并在使用之前解码“文件”。
use utf8;
use open qw( :std :encoding(UTF-8) );
use Encode qw( decode_utf8 );
my $text_ucp = "Žluťoučký kůň.";
open my $oh, ">", \my $text_utf8;
say $oh $text_ucp;
close $oh;
my $text2_ucp = decode_utf8($text_utf8);
... Do stuff with $text_ucp and/or $text2_ucp ...
say $text_ucp;
say $text2_ucp;
可以通过在程序的后半部分直接使用UTF-8来避免decode
。
use utf8;
BEGIN { binmode(STDERR, ":encoding(UTF-8)"); } # We'll handle STDOUT manually.
use open qw( :encoding(UTF-8) );
use Encode qw( encode_utf8 );
my $text_ucp = "Žluťoučký kůň.";
open my $oh, ">", \my $text_utf8;
say $oh $text_ucp;
close $oh;
say encode_utf8($text_ucp);
say $text_utf8;
当然,这意味着您无法在需要解码文本的任何地方使用$text_utf8
。