1
我有一个问题,我无法以适合于Stackoverflow的方式重现,尽管它在我的可重现生产环境。
问题occors在一个Perl脚本,除其他外,遍历一个文件,看起来像这样:
abc-4-9|free text, possibly containing non-ascii characters|
cde-3-8|hällo wörld|
# comment
xyz-9-1|and so on|
qrs-2-8|and so forth|
我可以验证这个Perl脚本文件的正确性:
use warnings;
use strict;
open (my $f, '<:encoding(UTF-8)', 'c:\path\to\file') or die "$!";
while (my $s = <$f>) {
chomp($s);
next unless $s;
next if $s =~ m/^#/;
$s =~ m!(\w+)-(\d+)-(\d+)\|([^|]*)\|! or die "\n>$s<\n didn't match on line $.";
}
print "Ok\n";
close $f;
当我运行这个脚本时,它不会死于第10行,因此打印Ok
。
现在,我在一个巨大的Perl脚本中使用基本相同的构造(因此对于Stackoverflow而言是不可再生的),它将死于输入文件的第2199行。
如果我改变的东西,从第一行(这是完全无关的行2199)像
www-1-1|A line with some words|
到
www-1-1|x|
脚本将处理线2199(但是后来失败)。
有趣的是,当我改变
open (my $f, '<', 'c:\path\to\file') or die "$!";
到
open (my $f, '<:encoding(UTF-8)', 'c:\path\to\file') or die "$!";
没有:encoding(UTF-8)
指令,此行为已出台,该脚本不会失败。当然,我需要编码指令,因为该文件包含非ASCII字符。
顺便说一句,同样的脚本在Linux上运行没有问题。
在Windows上,它失败了,我用草莓的Perl 5.24
该文件没有BOM。由于它包含机密数据,所以我不能不幸的只是复制并粘贴前几行。 –
添加'使用Devel :: Peek;'并用'Dump($ s)替换'die ...',死...'。请提供输出。 – ikegami
或者,用'do {use Data :: Dumper; local $ Data :: Dumper :: Useqq = 1; die Dumper($ s)'替换'die ...''。 “。(utf8 :: is_utf8($ s)?1:0)。”在$行。不匹配“};' – ikegami