我用Perl字符串比较运算符疯了吗?包括调试日志



我一定是错过了一些关于变量赋值或字符串比较。我有一个脚本,通过一个制表符分隔文件。除非一行中有一个特定的值是"P",否则我想跳到下一行。代码如下所示:

1 print "Processing inst_report file...n";
2 foreach(@inst_report_file){
3    @line=split(/t/);
4    ($line[13] ne "P") && next;
5    $inst_report{$line[1]}++;
6 }

由于某些原因,脚本永远不会到达第5行,即使其中明显有"p"行。

那么调试时间到了!

# Continuing to the breakpoint.
DB<13> c
main::(count.pl:27):        ($line[13] ne "P") && next;
# Proving that this particular array element is indeed "P" with no leading or trailing characters.
DB<13> p "--$line[13]--n";
--P--
# Proving that I'm not crazy and the Perl string comparison operator really works.
DB<14> p ("P" eq "P");
1
# Now since we've shown that $line[13] eq P, let's run that Boolean again.
DB<15> p ($line[13] eq "P")
# (Blank means FALSE) Whaaaat?
# Let's manually set $line[13]
DB<16> $line[13]="P"
# Now let's try that comparison again...
DB<17> p ($line[13] eq "P")
1
DB<18>
# Now it works.  Why?

我可以通过预过滤输入文件来解决这个问题,但让我困扰的是为什么这不起作用。我错过了什么明显的东西吗?

——罗兰——

找出你的字符串真正在使用什么:

use Data::Dumper;
local $Data::Dumper::Useqq = 1;
print(Dumper($line[13]));

[进一步审查,下面的猜测很可能是不正确的。])

我怀疑你有一个尾随换行符,在这种情况下你想要chomp

也可以有尾随空格。s/s+z//将删除尾随空格和尾随换行符。

你试过用ord打印出字符串字符吗?

say ord for (split //, $line[13]);

如果,例如,您在那里有一个,它可能不会显示在常规打印中。使用字符串P,我得到:

$ perl -wE '$a="P"; say "--$a--"; say ord for (split //, $a);'
--P--
80
0

除非输入中有不可打印的字符,否则不清楚您的代码为什么不能工作。话虽如此,我还是会这样写:

next unless $line[13] eq "P";

next unless $line[13] =~ /^P$/;(理论上可以更快)

您不需要预先过滤数据

你确定$line[13]不是$line[12]吗?

最新更新