Я схожу с ума от оператора сравнения строк Perl?Журнал отладки включен - PullRequest
3 голосов
/ 02 сентября 2011

Я должен что-то упустить из-за присваивания переменных или сравнения строк.У меня есть скрипт, который проходит через файл с разделителями табуляции.Если только одно конкретное значение в строке не является «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?

Я могу обойти это, предварительно отфильтровав входной файл, но беспокоит меня, почему это не работает.Я что-то упускаю из виду?

--- Лорен ---

Ответы [ 4 ]

4 голосов
/ 02 сентября 2011

Узнайте, что на самом деле использует ваша строка:

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

[При дальнейшем рассмотрении приведенные ниже предположения, скорее всего, неверны.]

Я подозреваю, что у вас есть завершающий символ новой строки, и в этом случае вы хотите chomp.

У вас также могут быть пробелы.s/\s+\z// удалит завершающие пробелы и завершающий перевод строки.

1 голос
/ 02 сентября 2011

Если на входе нет непечатаемых символов, непонятно, почему ваш код не работает. Сказав это, я все равно написал бы это заявление как:

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

или

next unless $line[13] =~ /^P$/; (Теоретически это может быть быстрее.)

Вам не нужно предварительно фильтровать данные.

1 голос
/ 02 сентября 2011

Вы пытались распечатать строковые символы с помощью 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
0 голосов
/ 08 сентября 2011

Вы уверены, что $ line [13] не должно быть $ line [12]?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...