Perl 相同的代码,不同机器上关于UTF8字符的不同结果

Perl 相同的代码,不同机器上关于UTF8字符的不同结果,perl,utf-8,Perl,Utf 8,我有以下代码: 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

我有以下代码:

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
Äeská SpoÅitelna - Q3 2014
Äeská SpoÅitelna - Q3 2014
在UAT机器上执行时(Aser验收测试),输出:

Česká Spořitelna - Q3 2014
Česká Spořitelna - Q3 2014
Äeská SpoÅitelna - Q3 2014
Äeská SpoÅitelna - Q3 2014
现在,在这两台机器上,当我运行
perl-v
时,我们看到的是为x86\u 64-linux-thread-multi-ld构建的Perl5,版本16,subversion 3(v5.16.3)

两台机器上的
HTML::Entities
版本相同:

    Installed: 3.69
    CPAN:      3.69  up to date
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=
我的开发机器运行的是CentOS 5.8版(最终版),UAT机器运行的是Red Hat Enterprise Linux Server 5.8版(Tikanga)

EDIT(关于
locale
命令的输出) 两台机器上的输出相同:

    Installed: 3.69
    CPAN:      3.69  up to date
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上发布了这个问题的链接,从中得到了一些非常有用的想法:比较两个系统上的输出字节。如果它们完全相同,那就是显示问题。他们是。现在,有不止一种方法可以做到这一点:

(一)

在两个系统上都显示
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
输出打印到每个系统上的文件中,然后对这些文件运行
hextump-C
,并比较输出。此方法还表明文件的内容是相同的

结论

这是一个显示问题-控制台(油灰)无法正确显示字符。
当我们在数据库中添加这些字符时,我们遇到了这个问题,我想我设法用上面的代码将其隔离。您的回答(以及来自fb的一些回答)帮助我发现
解码实体()
的工作方式与预期的一样,而我们的问题则存在于其他地方(最有可能是mysql表字符集或mysql连接)。

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

LANG=ro_RO.UTF-8
以及设置
STDOUT
,以在Perl中以这种方式对输出进行编码,例如

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

更新

我可以解释发生了什么,尽管我不确定为什么会这样

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

然而,在您的测试机器上,终端正在解码编码字符的第一个八位字节-
C4
,就好像它是ISO-8859-1,大写字母a umlaut一样。忽略第二个八位字节-
8C
,因为它是该编码中的无效字符


因此,您需要更改终端正在使用的代码页。实现这一点的方法是如我所述设置
LANG
,但我无法解释如果您的区域设置正确,它为什么不起作用。

检查两台机器上
locale
命令的输出。终端预期的不是UTF-8,而是输出UTF-8。调整终端期望的编码或调整使用的编码,使它们匹配。您如何连接到这些机器?您是否对这两个应用程序使用相同的终端程序?它是否具有特定于每个主机的设置?检查shell如何接受utf8 i/o。e、 g.试着用
touchČeskáKočka
ls
。使用bash?尝试设置<代码>设置转换元关闭;打开输入元;将输出元设置为on我已根据您的建议更新了问题-您还有其他想法吗?您的终端几乎肯定已设置为ISO-8859-1。查看我的更新。查看使用
echo$LANG
LANG
设置为什么。在数据库中添加这些字符时会出现问题。我想我用上面的代码把它隔离了。你的回答(以及一些来自fb的回答)帮助我发现
解码实体()
工作正常,问题(大概)与控制台(putty)有关@TudorConstantin:啊,你没有告诉我们putty的事!。它忽略了
LANG
的设置(毕竟,您没有在远程主机上运行PuTTY)。但一旦启动,您就会看到
PuTTY配置
,如果您选择窗口`/
Translation
,您可以选择
UTF-8
,问题就解决了。我希望你已经学会更好地解释你的问题了?没有人会猜到你坐在一个终端上,而这个终端并没有直接连接到你描述的两个系统。请写一个你自己的解决方案,并接受它,以将你的问题标记为已解决。嗯,正如我所说,我对正确显示字符不感兴趣。你的回答帮助我解决了这个问题,所以我接受你的回答。我更新了问题的细节,以供进一步参考:)