如何打开STDIN / STDOUT处理并正确使用utf8编码?

问题描述 投票:1回答:1

我的代码中包含utf8字符。所以我这样做:

use utf8;

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
print $line; # Wide character in print at ...

然后我认为我的STDOUT应该在utf8中:

use utf8;
use open IO => ':utf8 :std';

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
print $line; # Wide character in print at ...

为什么当我的源代码包含utf8个字符时我说Perl使用utf8时出现错误?

同时:

没有错误:

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
print $line;

没有错误:

use open IO => ':utf8 :std';

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
print $line;

我应该如何打开文件句柄并与utf8一起正常使用?

UPD其实我有这段代码。不匹配:

use open IO => ':utf8 :std';

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
my @match =  $line =~ m/(вiд|от|від)/i;
print "$line -> $1 \n";

很遗憾,正则表达式不匹配。输出为:

ЗГ. РАХ. №382 ВIД 03.02.2020Р ->

然后我添加utf8编译指示:

use utf8;
use open IO => ':utf8 :std';

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
my @match =  $line =~ m/(вiд|от|від)/i;
print "$line -> $1 \n";

现在正则表达式已匹配,但发出警告

Wide character in print at t2.pl line 17.
ЗГ. РАХ. №382 ВIД 03.02.2020Р -> ВIД
perl utf-8 file-io
1个回答
0
投票

感谢IRC中的@Grinnz

下一个代码有效:

use utf8;
use open ':encoding(UTF-8)', ':std';

my $line =  'ЗГ. РАХ. №382 ВIД 03.02.2020Р';
my @match =  $line =~ m/(вiд|от|від)/i;
print "$line -> $1 \n";

注意:@Grinnz建议使用https://metacpan.org/pod/open::layers因为:std is not a layer, it must be its own argument in the list

我也不应该使用:utf8 because

注意:请勿使用此层来转换UTF-8字节,因为无效的UTF-8或二进制数据将导致Perl字符串格式错误。用于输出时,它不太可能产生无效的UTF-8,尽管它将在EBCDIC系统上产生UTF-EBCDIC。 :encoding(UTF-8)层(连字符有效)是首选,因为它将确保有效的UTF-8字节和有效的Unicode字符之间的转换。

© www.soinside.com 2019 - 2024. All rights reserved.