提问人:Eric Johnson 提问时间:3/5/2013 最后编辑:Peter MortensenEric Johnson 更新时间:2/27/2023 访问量:73081
使用“use utf8;”给了我“打印中的宽字符”
Use of 'use utf8;' gives me 'Wide character in print'
问:
如果我运行以下 Perl 程序:
perl -e 'use utf8; print "鸡\n";'
我收到以下警告:
Wide character in print at -e line 1.
如果我运行这个 Perl 程序:
perl -e 'print "鸡\n";'
我没有收到警告。
我认为在 Perl 脚本中使用 UTF-8 字符是必需的。为什么这不起作用,我该如何解决?我正在使用 Perl 5.16.2。如果这是在文件中而不是命令行上的一行,我也有同样的问题。use utf8
答:
所有要做的就是告诉 Perl 源代码是使用 UTF-8 编码的。你需要告诉 Perl 如何对文本进行编码:use utf8;
use open ':std', ':encoding(UTF-8)';
评论
您可以使用 CPAN 模块 utf8::all 接近“到处都做 utf8
”。
perl -Mutf8::all -e 'print "鸡\n";'
当收到它无法打印的内容(未提供图层时大于 255 的字符)时,它会假定您打算使用 UTF-8 对其进行编码。在警告问题后,它会这样做。print
:encoding
Without Perl 将字符串解释为单字节字符序列。从中可以看出,字符串中有四个字节:use utf8
$ perl -E 'say join ":", map { ord } split //, "鸡\n";'
233:184:161:10
前三个字节组成您的字符,最后一个字节是换行符。
调用将这四个字符发送到 STDOUT。然后,您的控制台会计算出如何显示这些字符。如果您的控制台设置为使用 UTF8,那么它会将这三个字节解释为您的单个字符,这就是显示的内容。print
如果我们添加模块,情况就不同了。在这种情况下,Perl 将字符串解释为两个字符。utf8
$ 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'。关闭 warning 是不添加警告 'utf8';但这通常更接近 作弊。通常,您应该显式标记 File句柄,请参阅 Open 和 Perlfunc/binMode。
正如其他人所指出的,你需要告诉Perl接受多字节输出。有很多方法可以做到这一点(参见 Perl Unicode 教程中的一些示例)。最简单的方法之一是使用命令行标志 - 它告诉三个标准文件句柄(STDIN、STDOUT 和 STDERR)处理 UTF8。-CS
$ perl -Mutf8 -e 'print "鸡\n";'
Wide character in print at -e line 1.
鸡
与
$ perl -Mutf8 -CS -e 'print "鸡\n";'
鸡
Unicode是一个庞大而复杂的领域。正如你所看到的,许多简单的程序似乎在做正确的事情,但出于错误的原因。当您开始修复部分程序时,情况通常会变得更糟,直到您修复了所有程序。
评论
-Mutf8
use utf8;
将所有标准输出编码为 UTF-8:
binmode STDOUT, ":utf8";
评论
use open ':std', ':encoding(UTF-8)';
正如另一个答案所建议的那样,STDOUT 会这样做,但也会将 STDERR 和 STDIN 标记为 UTF-8,因此您可以以一个语句的价格获得三个。另请参阅 stackoverflow.com/a/42194059
BEGIN {binmode STDOUT, ":utf8";} print "\x{201C}in curly quotes\x{201D}\n";
你可以用这个,
perl -CS filename.
它还将终止该错误。
参考资料(删节):
The -C flag controls some of the Perl Unicode features.
As of 5.8.1, the -C can be followed either by a number or a list of option letters. The letters, their numeric values,
and effects are as follows; listing the letters is equal to summing the numbers.
I 1 STDIN is assumed to be in UTF-8
O 2 STDOUT will be in UTF-8
E 4 STDERR will be in UTF-8
S 7 I + O + E
评论
在西班牙语中,您可以在开始使用时发现此错误:
use utf8;
编辑器编码采用不同的编码。所以你在编辑器上看到的不是Perl所做的。要解决该错误,只需将编辑器编码更改为 Unicode/UTF-8。
评论