Perl使用编码pragma破坏UTF字符串

时间:2011-03-19 15:43:56

标签: perl

我遇到了Perl和编码编译指示的问题。

(我在输入,输出,perl脚本本身使用utf-8。我不想使用其他编码,从来没有。)

然而。我写的时候

binmode(STDOUT, ':utf8');
use utf8;
$r = "\x{ed}";
print $r;

我看到字符串“í”(这就是我想要的 - 以及什么是U + 00ED unicode char)。但是当我像这样添加“use encoding”pragma时

binmode(STDOUT, ':utf8');
use utf8;
use encoding 'utf8';
$r = "\x{ed}";
print $r;

我看到的只是一个盒子角色。为什么呢?

此外,当我添加Data :: Dumper并让Dumper打印出像这样的新字符串

binmode(STDOUT, ':utf8');
use utf8;
use encoding 'utf8';
$r = "\x{ed}";
use Data::Dumper;
print Dumper($r);

我看到perl 将字符串更改为"\x{fffd}"。为什么呢?

2 个答案:

答案 0 :(得分:9)

use encoding 'utf8'被打破了。它不是将\x{ed}解释为代码点U + 00ED,而是将其解释为单个字节237,然后尝试将其解释为UTF-8。当然哪个失败了,所以它最终用替换字符U + FFFD替换它,字面意思是“ ”。

坚持使用use utf8指定您的来源是UTF-8,binmodeopen pragma指定文件句柄的编码。

答案 1 :(得分:5)

您的实际代码既不需要use encoding也不需要use utf8才能正常运行 - 它唯一依赖的是STDOUT上的编码层。

binmode(STDOUT, ":utf8");
print "\xed";

是一个同样有效的完整程序,可以满足您的需求。

仅当您的程序中的文字字符串中包含UTF-8时,才应使用

use utf8 - 例如如果你写过

my $r = "í";

然后use utf8会导致该字符串被解释为单个字符U + 00ED而不是C3 AD的字节序列。

永远不应该使用

use encoding,尤其是喜欢Unicode的人。如果您希望更改stdin / out的编码,则应使用-CPERLUNICODE或自己对其进行binmode,如果您希望使用编码层自动打开其他句柄,则应{{1} } open