2

这是 - 减少到最低限度 - 我用来读取和解释一些 UTF8 文本文件的程序:

use 5.012;
use utf8;
binmode STDIN, ':utf8';
binmode STDOUT, ':utf8';

while (<>) {
    chomp;
    if ($_ =~ /BOLETIM DE ANÁLISE N/) {print "Boletim\n";}
    if ($_ =~ /DADOS REFERENTES A AMOSTRA/) {print "Dados\n";}
}

输入文件包含应该满足两个正则表达式的行,并且我使用 TextWrangler 验证该文件确实是 UTF-8 格式,带有 Unix endlines。但是,该程序只识别第二个,它不包含重音字符。

奇怪的是(至少对我来说)当我在调试器中运行同一行时

    x if ($_ =~ /BOLETIM DE ANÁLISE N/) {print "Boletim\n";}

当 $_ 是 string'BOLETIM DE ANÁLISE N° 274734/2011-0 '时,正则表达式触发并打印“Boletim”。

为什么调试器和程序应该有不同的行为?

提前谢谢了

阿德里亚诺

PS 我在 Mac Os X 10.7.5 和 Perl v5.12.4 上。

4

1 回答 1

2

您没有正确解码 UTF-8 文件。

大写字母 A的 Unicode 值是1930xC1。您的匹配结果AN(.*)LISE表明您对该字符具有多字节表示,以 . 开头195。该字符的 UTF-8 编码是C3 81(或195 129十进制),因此您正在查看两个单字节字符而不是单字节字符C1

您可以通过写信来确认这一点

print join ' ', map sprintf('%02X', ord), split //, $1;

比赛操作后。你会得到C3 81.

您使用 设置STDINSTDOUT使用utf8图层binmode,但<>运算符从ARGV文件句柄中读取,除非@ARGV为空。

我建议你写

binmode ARGV, ':utf8';

还可以解码从ARGV. 那么一切都应该很好。

于 2013-04-26T17:16:49.950 回答