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

Eri*_*son 80 unicode perl utf-8

如果我运行以下Perl程序:

perl -e 'use utf8; print "?\n";'
Run Code Online (Sandbox Code Playgroud)

我收到这个警告:

Wide character in print at -e line 1.
Run Code Online (Sandbox Code Playgroud)

如果我运行这个Perl程序:

perl -e 'print "?\n";'
Run Code Online (Sandbox Code Playgroud)

我没有收到警告.

我认为use utf8需要在Perl脚本中使用UTF-8字符.为什么这不起作用,我该如何解决?我正在使用Perl 5.16.2.我有同样的问题,如果这是在一个文件而不是命令行上的一个班轮.

Dav*_*oss 105

没有use utf8Perl会将您的字符串解释为单字节字符序列.您可以从中看到字符串中有四个字节:

$ perl -E 'say join ":", map { ord } split //, "?\n";'
233:184:161:10
Run Code Online (Sandbox Code Playgroud)

前三个字节组成你的角色,最后一个是换行.

调用print将这四个字符发送到STDOUT.然后,您的控制台将确定如何显示这些字符.如果您的控制台设置为使用UTF8,那么它会将这三个字节解释为您的单个字符,这就是显示的内容.

如果我们添加utf8模块,事情就会有所不同.在这种情况下,Perl会将您的字符串解释为两个字符.

$ perl -Mutf8 -E 'say join ":", map { ord } split //, "?\n";'
40481:10
Run Code Online (Sandbox Code Playgroud)

默认情况下,Perl的IO层假定它使用单字节字符.因此,当您尝试打印多字节字符时,Perl会认为某些内容出错并给您一个警告.与以往一样,您可以通过包含来获得有关此错误的更多解释use diagnostics.它会说:

(S utf8)Perl遇到一个广泛的角色(> 255),当它没有期待的时候.默认情况下,此警告用于I/O(如打印).安静此警告的最简单方法是将:utf8图层添加到输出中,例如binmode STDOUT,':utf8'.另一种关闭警告的方法是不添加警告'utf8'; 但这通常更接近作弊.通常,您应该使用编码显式标记文件句柄,请参阅open和perlfunc/binmode.

正如其他人指出的那样,你需要告诉Perl接受多字节输出.有很多方法可以做到这一点(有关示例,请参阅Perl Unicode教程).最简单的方法之一是使用-CS命令行标志 - 它告诉三个标准文件句柄(STDIN,STDOUT和STDERR)来处理UTF8.

$ perl -Mutf8 -e 'print "?\n";'
Wide character in print at -e line 1.
?
Run Code Online (Sandbox Code Playgroud)

VS

$ perl -Mutf8 -CS -e 'print "?\n";'
?
Run Code Online (Sandbox Code Playgroud)

Unicode是一个庞大而复杂的领域.正如您所见,许多简单的程序看起来做得对,但出于错误的原因.当您启动修复计划的一部分,事情往往会变得更糟,直到你固定所有的程序.


ike*_*ami 72

所有这些use utf8;都告诉Perl源代码使用UTF-8编码.您需要告诉Perl如何编码您的文本:

use open ':std', ':encoding(UTF-8)';
Run Code Online (Sandbox Code Playgroud)


Bor*_*nov 18

将所有标准输出编码为UTF-8:

binmode STDOUT, ":utf8";
Run Code Online (Sandbox Code Playgroud)

  • 正如另一个答案所建议的那样,`use open ':std', ':encoding(UTF-8)';` 对 STDOUT 执行此操作,但也将 STDERR 和 STDIN 标记为 UTF-8,因此您可以用一个语句的价格得到三个。另请参阅 /sf/answers/2953584161/ (2认同)

Joe*_*ger 12

您可以使用CPAN模块接近"只需在任何地方执行utf8" utf8::all.

perl -Mutf8::all -e 'print "?\n";'
Run Code Online (Sandbox Code Playgroud)

print收到无法打印的内容(当没有:encoding提供图层时,字符大于255 ),它假定您打算使用UTF-8对其进行编码.它在警告问题之后这样做了.


Kar*_*R.S 5

你可以用这个,

perl -CS filename.
Run Code Online (Sandbox Code Playgroud)

它也将终止该错误.