perl - 如何使用菱形运算符 (<>) 读取 UTF-8?

标签 perl unicode utf-8 input

我想在 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\xA7bcat的方法正确输出:

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/

相关文章:

perl - 为什么对于包含非 ASCII 字符的文件名,-e 文件存在性测试总是返回 false?

php - Joomla UTF-8 编码在打开邮件时失败

css - 如何仅将字体应用于一定范围的 Unicode 字符

perl - 替换大文件中的最后一个字符

perl - 未定义 uselongdouble 而在 Perl 构建配置中定义了 d_longdbl 是什么意思?

vim - 在vim搜索和替换中,换行符呈现为“^ @”

qt - QUrl,路径的正确编码

PHP: strpos & substr with UTF-8

perl - 当我想打印到哈希键中的句柄时,为什么会出现语法错误?

Python 不打开日文文件名