不使用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
。它会这样说:
(Sutf8)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.
鸡
与
$ perl -Mutf8 -CS -e 'print "鸡\n";'
鸡
Unicode是一个庞大而复杂的领域。如您所见,许多简单的程序似乎在做正确的事情,但是出于错误的原因。当您开始修复程序的一部分时,往往会变得更糟,直到您修复了所有程序。