我有这个代码:

use strict;
use warnings;
use utf8;
use HTML::Entities;
use feature 'say';

binmode STDOUT, ':encoding(utf-8)';

my $t1 = "Česká Spořitelna - Q3 2014";
my $t2 =  "Česká Spořitelna - Q3 2014";

say decode_entities($t1);
say decode_entities($t2);

在我的开发机器上执行时,输出:
Česká Spořitelna - Q3 2014
Česká Spořitelna - Q3 2014

当在 UAT 机器上执行时(Aser Acceptance Test),输出:
Äeská SpoÅitelna - Q3 2014
Äeská SpoÅitelna - Q3 2014

现在,在两台机器上,当我运行 perl -v 时,我们有这是为 x86_64-linux-thread-multi-ld 构建的 perl 5, version 16, subversion 3 (v5.16.3)

并且 HTML::Entities 的版本在两台机器上是相同的:
    Installed: 3.69
    CPAN:      3.69  up to date

我的开发机器运行 CentOS release 5.8 (Final) 而 UAT 机器运行 Red Hat Enterprise Linux Server release 5.8 (Tikanga)
编辑 (关于 locale 命令的输出)
它的输出在两台机器上是相同的:
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

更新 :

我在 facebook 上的 perl developers 组上发布了这个问题的链接,并从那里得到了一些非常有用的想法:比较两个系统上的输出字节。如果它们相同,则是显示问题。他们是。现在, 有不止一种方法可以做到 :

1)
say join ':', map { ord } split //, decode_entities($t1);
say join ':', map { ord } split //, decode_entities($t2);

它在两个系统上都显示 268:101:115:107:225:32:83:112:111:345:105:116:101:108:110:97:32:45:32:81:51:32:50:48:49:52,因此字节是相同的

2) 将 $t1$t2 输出打印到每个系统上的文件中,然后对这些文件运行 hexdump -C 并比较输出。这个方法也表明文件的内容是一样的

结论

这是一个显示问题 - 控制台(腻子)没有正确显示字符。
当我们在数据库中添加这些字符时,我们遇到了这个问题,我想我设法用上面的代码隔离了它。您的回答(以及一些来自 fb 的回答)帮助我发现 decode_entities() 按预期工作,而我们的问题出在其他地方(很可能在 mysql 表字符集或 mysql 连接中)。

最佳答案

命令终端期望的编码是不同的。如果要打印 UTF-8,则必须将两个终端都设置为期望 UTF-8,例如对于罗马尼亚语

LANG=ro_RO.UTF-8

以及设置 STDOUT 以在 Perl 中以这种方式对输出进行编码,例如
binmode STDOUT, ':encoding(utf-8)'

更新

我可以解释正在发生的事情,尽管我不确定为什么会这样。

取字符串的第一个字符:"\x{010C}",它是一个大写的 C caron。 Perl 将其编码为两个八位字节的代码 "\x{C4}\x{8C}" 并发送到终端,终端在您的开发机器上对其进行解码并正确显示。

但是,在您的测试机器上,终端正在解码编码字符的第一个八位字节 - C4 - 好像它是 ISO-8859-1,一个大写的 A 变音符号。第二个八位字节 - 8C - 被忽略,因为它是该编码中的无效字符。

因此,您需要更改终端正在使用的代码页。这样做的方法是按照我的描述设置 LANG,但是如果您的语言环境设置正确,我无法解释为什么它不起作用。

关于perl - 相同的代码,不同机器上关于 UTF8 字符的不同结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25527512/

10-15 04:57