为什么这个Perl正则表达式失败了?

时间:2009-01-21 22:19:22

标签: regex perl

我有以下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”,那么它就会成功。如果我用常量字符串(“Just A Minute”)替换$progName变量,那么它会成功。当它打印$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 个答案:

答案 0 :(得分:1)

你的程序(第一个)对我来说很好。

请注意,您必须引用参数sting(因为它包含空格),否则您只是在寻找与“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线后的空白行。那是因为你没有从文件中读取的行中删除换行符。因此在“Foo \ n”和“Bar \ n”的末尾有一个“\ n”,它会在输出中打印出来。但这不会影响匹配。

答案 1 :(得分:0)

您的示例似乎没有任何问题。它在我的测试中运行得很好。

你能给我们看一下你看到的完整错误输出,如“Y中匹配X失败”输出吗?

我唯一能想到的是$progName未设置为正确的值。看到完整的错误输出会排除这一点。

答案 2 :(得分:0)

检查你的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

答案 3 :(得分:0)

我会尝试明天发布更好的测试结果等。我需要提取函数并首先将其包装起来。现在是时候睡觉了!

答案 4 :(得分:0)

如果您的列表是HTML格式,您可以保证在浏览器中看到的“只需一分钟”实际上是源代码中的“只需一分钟”吗?

可能是

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

依旧等等。

向我们展示HTML。

答案 5 :(得分:0)

我将整个函数提取到一个测试程序中,它运行得很完美!在重新发布此问题之前,我将不得不花一些时间隔离问题。目前看来我必须发布整个700行程序,并提供支持文件和指令以允许人们测试它,这超出了stackoverflow的范围。

--- Alistair。