Perl的YAML :: XS和unicode

Kar*_*lek 3 unicode perl yaml

我试图YAML::XS在unicode字母上使用perl的模块,它似乎没有按照应有的方式工作.

我在脚本中写了这个(保存在utf-8中)

use utf8;
binmode STDOUT, ":utf8"; 
my $hash = {? => "?"}; #czech letters with unicode codes U+010D and U+0159

use YAML::XS;
my $s = YAML::XS::Dump($hash);
print $s;
Run Code Online (Sandbox Code Playgroud)

-: Å印刷而不是理智.但是,根据这个链接,它应该工作正常.

是的,当我YAML::XS::Load回来时,我再次获得了正确的字符串,但我不喜欢转储字符串似乎是在一些错误的编码中的事实.

难道我做错了什么?我总是不确定perl中的unicode,坦率地说......

澄清:我的控制台支持UTF-8.此外,当我将其打印到文件时,用utf8句柄打开open $file, ">:utf8"而不是STDOUT,它仍然不能打印正确的utf-8字母.

cjm*_*cjm 7

是的,你做错了什么.你误解了你提到的链接意味着什么. Dump&Load与原始UTF-8字节工作; 即包含UTF-8但UTF-8标志关闭的字符串.

当您将这些字节打印到带有:utf8图层的文件句柄时,它们会被解释为Latin-1并转换为UTF-8,从而产生双编码输出(只要您对其进行双重解码,就可以成功读回).你想binmode STDOUT, ':raw'改为.

另一种选择是在返回的字符串上调用utf8 :: decodeDump.这会将原始UTF-8字节转换为字符串(打开UTF-8标志).然后,您可以将字符串打印到:utf8文件句柄.

所以,要么

use utf8;
binmode STDOUT, ":raw"; 
my $hash = {? => "?"}; #czech letters with unicode codes U+010D and U+0159

use YAML::XS;
my $s = YAML::XS::Dump($hash);
print $s;
Run Code Online (Sandbox Code Playgroud)

要么

use utf8;
binmode STDOUT, ":utf8"; 
my $hash = {? => "?"}; #czech letters with unicode codes U+010D and U+0159

use YAML::XS;
my $s = YAML::XS::Dump($hash);
utf8::decode($s);
print $s;
Run Code Online (Sandbox Code Playgroud)

同样,从文件读取时,您希望在传入:raw模式utf8::encode之前读取模式或使用字符串Load.

如果可能,您应该只使用DumpFile&LoadFile,让YAML :: XS处理正确打开文件.但是如果你想使用STDIN/STDOUT,你将不得不处理Dump&Load.