如果我运行以下Perl程序:
perl -e 'use utf8; print "鸡\n";'
我收到了这个警告:
Wide character in print at -e line 1.
如果我运行这个Perl程序:
perl -e 'print "鸡\n";'
我没有收到警告。
我认为在Perl脚本中使用UTF-8字符需要use utf8
。为什么这不起作用,我该如何解决?我正在使用Perl 5.16.2。如果这是在一个文件中,而不是在命令行上单行,我有同样的问题。
答案 0 :(得分:103)
没有use utf8
Perl将您的字符串解释为单字节字符序列。从中可以看出,字符串中有四个字节:
$ perl -E 'say join ":", map { ord } split //, "鸡\n";'
233:184:161:10
前三个字节构成你的角色,最后一个是换行。
对print
的调用会将这四个字符发送给STDOUT。然后,您的控制台将确定如何显示这些字符。如果您的控制台设置为使用UTF8,那么它会将这三个字节解释为您的单个字符,这就是显示的内容。
如果我们添加utf8
模块,情况会有所不同。在这种情况下,Perl会将您的字符串解释为两个字符。
$ perl -Mutf8 -E 'say join ":", map { ord } split //, "鸡\n";'
40481:10
默认情况下,Perl的IO层假定它使用单字节字符。因此,当您尝试打印多字节字符时,Perl认为出现了问题并给出了警告。与以往一样,您可以通过添加use diagnostics
来获得有关此错误的更多解释。它会说:
(S utf8)Perl在不期待的时候遇到了一个宽字符(> 255) 一。默认情况下,此警告用于I / O(如打印)。最简单的 安静此警告的方法只是将:utf8图层添加到 输出,例如binmode STDOUT,':utf8'。另一种关闭方式 警告是不添加警告'utf8';但那往往更接近 作弊。一般来说,你应该明确标记 带编码的文件句柄,请参阅open和perlfunc / binmode。
正如其他人指出的那样,你需要告诉Perl接受多字节输出。有很多方法可以做到这一点(有关示例,请参阅Perl Unicode Tutorial)。最简单的方法之一是使用-CS
命令行标志 - 它告诉三个标准文件句柄(STDIN,STDOUT和STDERR)来处理UTF8。
$ perl -Mutf8 -e 'print "鸡\n";'
Wide character in print at -e line 1.
鸡
VS
$ perl -Mutf8 -CS -e 'print "鸡\n";'
鸡
Unicode是一个庞大而复杂的领域。正如您所见,许多简单的程序看起来做得对,但出于错误的原因。当你开始修复程序的一部分时,在修复所有程序之前,事情往往会变得更糟。
答案 1 :(得分:69)
所有use utf8;
都告诉Perl源代码是使用UTF-8编码的。您需要告诉Perl如何对文本进行编码:
use open ':std', ':encoding(UTF-8)';
答案 2 :(得分:17)
将所有标准输出编码为UTF-8:
binmode STDOUT, ":utf8";
答案 3 :(得分:12)
您可以使用CPAN模块utf8::all
接近“只需在任何地方执行utf8”。
perl -Mutf8::all -e 'print "鸡\n";'
当print
收到无法打印的内容时(如果没有提供:encoding
图层,则字符大于255),它假定您打算使用UTF-8对其进行编码。在对此问题发出警告后,它会这样做。
答案 4 :(得分:5)
你可以使用它,
perl -CS filename.
它也会终止该错误。
答案 5 :(得分:0)
在西班牙语中,您可以在开始使用时找到此错误:
use utf8;
您的编辑器编码采用不同的编码方式。所以你在编辑器上看到的并不是Perl所做的。要解决该错误,只需将编辑器编码更改为 Unicode / UTF-8 。