使用'use utf8;'给了我'印刷品的广泛性'

时间:2013-03-04 20:29:51

标签: perl unicode utf-8

如果我运行以下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。如果这是在一个文件中,而不是在命令行上单行,我有同样的问题。

6 个答案:

答案 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