Почему это Perl регулярное выражение терпит неудачу? - PullRequest
0 голосов
/ 22 января 2009

У меня есть следующий код Perl:

my $progName = shift ;

open(IPLAYERLIST, "iplayer-list.html") or die "Cannot open iplayer index file iplayer-list.html\n" ;
while (<IPLAYERLIST>) {

    if ( /($progName)/is ) {
    #if ( /Just A Minute/is ) { <-- This works!
        my $iplayerID = $1 ;
        print "IPlayer program id for $progName is $iplayerID\n" ;

        #  === do stuff here ===
    }
    else
    {
        print "Failed to match $progName in $_\n";
    }
}

IPLAYERLIST - это список BBC IPlayer, поэтому он ищет определенное имя программы.

Если я вызываю это с $progName = "Just A Minute", он не совпадает, даже если строка находится в файле. Если я называю это одним символом, например, «M», то это успешно. Если я заменю переменную $progName на постоянную строку («Just A Minute»), то это будет успешно. Когда он печатает $progName, он всегда печатает правильную строку, поэтому я не вижу, как регулярное выражение может получить что-то другое.

Я вырезал код и вставил его в тестовый скрипт:

#!/usr/bin/perl
use strict ;

my $searchstr = "foo bar Just A Minute baz boo" ;
my $progName = $ARGV[0] ;
print "searching for [$progName] in [$searchstr]\n" ;
if ( $searchstr =~ /$progName/is ) {
    print "Well the test worked\n" ;
} else {
    print "Failed to match [$progName] in [$searchstr]\n";
}

и это прекрасно работает. Так почему первый пример не находит «Just A Minute» в файле, содержащем «Just A Minute»?!?!?

Ответы [ 6 ]

1 голос
/ 22 января 2009

Ваша программа (первая) у меня работает нормально.

Обратите внимание, что вы должны заключить строку аргумента в кавычки (потому что она содержит пробелы), иначе вы просто ищете совпадение с "Just" Так запусти это так ...

perl yourprog.pl "Всего минуту"

Я запустил его с этим входным файлом:

Foo
Just A Minute
Bar

Какие выходы ...

Failed to match Just A Minute in Foo

IPlayer program id for Just A Minute is Just A Minute
Failed to match Just A Minute in Bar

Обратите внимание на пустые строки после строк Foo и Bar. Это потому, что вы не удаляете символы новой строки из строк, прочитанных из файла. Таким образом, есть «\ n» в конце «Foo \ n» и «Bar \ n», которые печатаются в выводе. Но это не влияет на сопоставление.

0 голосов
/ 23 января 2009

Я извлек всю функцию в тестовую программу, и она отлично работала! Мне придется потратить некоторое время на то, чтобы изолировать проблему, прежде чем я снова напишу этот вопрос. На данный момент мне кажется, что мне нужно было бы опубликовать всю 700-строчную программу с вспомогательными файлами и инструкциями, чтобы люди могли ее протестировать, что выходит за рамки стекового потока.

--- Алистер.

0 голосов
/ 22 января 2009

Если ваш список в формате HTML, какова ваша гарантия того, что «Just A Minute», который вы видите в браузере, на самом деле «Just A Minute» в вашем исходном коде?

Это может быть

Just    A    Minute (extra spaces)
Just  
A  
Minute
Just <!--comment-->A Minute
Just[the nbsp entity]A Minute

и т. Д. И т. П.

Покажите нам HTML.

0 голосов
/ 22 января 2009

Я постараюсь опубликовать лучший тест с результатами и т.д. завтра. Мне нужно будет извлечь функцию и обернуть ее в первую очередь. Сейчас настало время ложиться спать!

0 голосов
/ 22 января 2009

Проверьте ваш HTML-файл.

Я запустил следующее

my $progName = shift ;

open(IPLAYERLIST, "list.txt") or die "Cannot open iplayer index file\n" ;
while (<IPLAYERLIST>) {

        if ( /($progName)/is ) {
        #if ( /Just A Minute/is ) { <-- This works!
                my $iplayerID = $1 ;
                print "IPlayer program id for $progName is $iplayerID\n" ;

                #  === do stuff here ===
        }
        else
        {
                print "Failed to match $progName in $_\n";
        }
}

со следующим файлом list.txt:

egg
spam
foo bar Just A Minute baz boo
egg spam Just A Minute spam egg
foo
bar

Вроде работает, вывод для perl prog.pl "just a minute" равен

Failed to match just a minute in egg

Failed to match just a minute in spam

IPlayer program id for just a minute is Just A Minute
IPlayer program id for just a minute is Just A Minute
Failed to match just a minute in foo

Failed to match just a minute in bar
0 голосов
/ 22 января 2009

В вашем примере нет ничего плохого. Он отлично работает в моих тестах.

Можете ли вы дать нам полный вывод ошибок, который вы видите, как в выводе "Не удалось сопоставить X в Y"?

Единственное, о чем я могу думать, это то, что $progName не имеет правильного значения. Просмотр полной информации об ошибке исключит это.

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