我是否对Perl字符串比较运算符感到疯狂?包含调试日志

时间:2011-09-01 23:34:50

标签: string perl comparison

我必须遗漏一些有关变量赋值或字符串比较的内容。我有一个脚本,它通过一个制表符分隔文件。除非一行中的一个特定值是“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 }

出于某种原因,即使在其中有明显的“P”行,脚本也永远不会到达第5行。

所以调试时间!

# 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?

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

--- ---洛伦

4 个答案:

答案 0 :(得分:4)

找出你的字符串使用的是什么:

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

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

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

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

答案 1 :(得分:1)

您是否尝试使用ord打印出字符串字符?

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

例如,如果您有\0,则可能不会以常规打印显示。使用字符串P\0,我得到:

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

答案 2 :(得分:1)

除非输入中有不可打印的字符,否则不清楚为什么你的代码不起作用。话虽如此,我仍然会把这句话写成:

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

next unless $line[13] =~ /^P$/;(从理论上讲,这可能会更快。)

您无需预先过滤数据。

答案 3 :(得分:0)

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