我有这个代码:
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);
Run Code Online (Sandbox Code Playgroud)
在我的开发机器上执行时输出:
?eská Spo?itelna - Q3 2014
?eská Spo?itelna - Q3 2014
Run Code Online (Sandbox Code Playgroud)
当在UAT机器上执行(Aser Acceptance Test)时,输出:
Äeská SpoÅitelna - Q3 2014
Äeská SpoÅitelna - Q3 2014
Run Code Online (Sandbox Code Playgroud)
现在,在两台机器上,当我运行时,perl -v我们有这是为x86_64-linux-thread-multi-ld构建的perl 5,版本16,subversion 3(v5.16.3)
并且HTML::Entities两台机器上的版本相同:
Installed: 3.69
CPAN: 3.69 up to date
Run Code Online (Sandbox Code Playgroud)
我的开发机器运行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=
Run Code Online (Sandbox Code Playgroud)
更新:
我在facebook 上的perl开发者小组发布了这个问题的链接,并从那里得到了一些非常有用的想法:比较两个系统上的输出字节.如果它们相同,那就是显示问题.他们是.现在,有多种方法可以做到:
1)
say join ':', map { ord } split //, decode_entities($t1);
say join ':', map { ord } split //, decode_entities($t2);
Run Code Online (Sandbox Code Playgroud)
它显示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针对这些文件运行并比较输出.此方法还显示文件的内容相同
结论
这是一个显示问题 - 控制台(putty)没有正确显示字符.当我们在数据库中添加这些字符时,我们遇到了这个问题,我认为我设法用上面的代码隔离它.你的答案(以及fb中的一些)帮助我找到了decode_entities()预期的工作,我们的问题在于其他地方(很可能在mysql表charset或mysql连接).
命令终端期望的编码是不同的.如果要打印UTF-8,则必须将两个终端设置为期望UTF-8,例如罗马尼亚语
LANG=ro_RO.UTF-8
Run Code Online (Sandbox Code Playgroud)
例如,设置STDOUT为在Perl中以这种方式编码输出
binmode STDOUT, ':encoding(utf-8)'
Run Code Online (Sandbox Code Playgroud)
更新
我可以解释发生了什么,虽然这就是为什么我不确定.
取字符串的第一个字符:"\x{010C}"这是一个大写的C caron.这是由Perl编码为两个八位字节代码"\x{C4}\x{8C}"并发送到终端,终端在您的开发机器上解码并正确显示它.
但是,在您的测试机器上,终端正在解码编码字符的第一个八位字节C4- 就好像它是ISO-8859-1,一个资本A变音符号.第二个八位字节 - 8C- 被忽略,因为它在该编码中是无效字符.
因此,您需要更改终端正在使用的代码页.这样做的方法是LANG按照我的描述进行设置,但如果您的语言环境设置正确,我无法解释为什么它不起作用.
| 归档时间: |
|
| 查看次数: |
252 次 |
| 最近记录: |