我想在 Perl 中读取 UTF-8 输入,无论它来自标准输入还是文件,使用菱形运算符:while(<>){...}
.
所以我的脚本应该可以像往常一样通过这两种方式调用,并给出相同的输出:
./script.pl utf8.txt
cat utf8.txt | ./script.pl
但是输出不同!只有第二次调用(使用 cat
)似乎按设计工作,正确读取 UTF-8。这是脚本:
#!/usr/bin/perl -w
binmode STDIN, ':utf8';
binmode STDOUT, ':utf8';
while(<>){
my @chars = split //, $_;
print "$_\n" foreach(@chars);
}
如何让它在这两种情况下都能正确读取 UTF-8?我想继续使用钻石运算符 <>
如果可能的话,供阅读。
编辑:
我意识到我应该描述不同的输出。我的输入文件包含以下序列:a\xCA\xA7b
。 cat
的方法正确输出:
a
\xCA\xA7
b
但是另一种方法给了我这个:
a
\xC3\x8A
\xC2\xA7
b
最佳答案
尝试使用 pragma open 来代替:
use strict;
use warnings;
use open qw(:std :utf8);
while(<>){
my @chars = split //, $_;
print "$_" foreach(@chars);
}
您需要这样做,因为 <> 运算符很神奇。如您所知,它将从 STDIN 或 @ARGV 中的文件读取。从 STDIN 读取不会产生任何问题,因为 STDIN 已经打开,因此 binmode 可以很好地工作。问题是从 @ARGV 中的文件读取时,当脚本启动并调用 binmode 时,文件未打开。这会导致 STDIN 设置为 UTF-8,但当 @ARGV 有文件时不使用此 IO channel 。在这种情况下,<>运算符为@ARGV中的每个文件打开一个新的文件句柄。每个文件句柄都会重置并丢失其 UTF-8 属性。通过使用 pragma open,您可以强制每个新的 STDIN 采用 UTF-8。
关于perl - 如何使用菱形运算符 (<>) 读取 UTF-8?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/519309/