将Perl UTF8输出到变量

将Perl UTF8输出到变量,perl,utf-8,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 $outpu

我有以下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)
,打开$oh,但都没用


我可能在做一些愚蠢的事情,但我不知道如何解决这个问题。有什么想法吗?

首先,
:编码(utf8)
应该是
:编码(utf-8)

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

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


使用openqw(:std:encoding(utf8))有两种效果:

  • 它将
    :编码(utf8)
    添加到
    STDIN
    STDOUT
    STDERR
  • 它将
    use
    的词法范围中的
    open
    的默认层设置为
    :encoding(utf8)
所以

您试图覆盖
使用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,可以避免
解码

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\u utf8

好的,所以一个快速的解决方案是在关闭“$oh$”后运行
utf8::decode($output)
,但是没有更好的解决方案吗?好的,我知道我必须对变量运行utf8::decode或decode\u utf8,并且没有更好的解决方案。谢谢。为了清楚起见,这个愚蠢的问题是:
utf8
ne
utf-8
,is
utf-8
eq
utf-8
,为了
:encoding()
?@Jim Davis的目的,编码名称不区分大小写。
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;