Perl UTF8输出到变量

Nik*_*nes 0 perl utf-8

我有以下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;
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我得到以下输出:

Žlu?ou?ký k??.
ŽluÅ¥ouÄký kůÅ.
Run Code Online (Sandbox Code Playgroud)

(没有任何警告或错误).因此,显然,通过句柄将utf8字符串写入变量在此处无法正常工作,因为字符串似乎是双重编码的.我试图打开$呵,>:raw,>:bytes,>:encoding(ascii),但没有它的帮助.

我可能会做一些愚蠢的事情,但我无法弄清楚如何解决这个问题.有任何想法吗?

ike*_*ami 7

首先,:encoding(utf8)应该是:encoding(utf-8).

  • UTF-8 是众所周知的编码标准.
  • utf8 是UTF-8的Perl特定扩展.

参考

(编码名称不区分大小写.)


use open qw( :std :encoding(utf8) ); 有两个影响:

  • 它增加:encoding(utf8)STDIN,STDOUTSTDERR.
  • 它为to 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;
Run Code Online (Sandbox Code Playgroud)

您试图覆盖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;
Run Code Online (Sandbox Code Playgroud)

可以避免decode在程序的后半部分直接使用UTF-8.

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;
Run Code Online (Sandbox Code Playgroud)

当然,这意味着您无法$text_utf8在任何需要解码文本的地方使用.

  • @Jim Davis,编码名称不区分大小写. (2认同)