正则表达式匹配,但1美元未初始化

时间:2015-07-08 08:27:49

标签: regex perl

我的代码段:

my $URL_PATTERN = qr/http.*html/;
foreach my $urlCandidate(@urlCandidates)
{
    if ($urlCandidate !~ $URL_PATTERN)
    {
        next;
    }
    my $url = $1;
    if ($url !~ $SOME_OTHER_PATTERN)   # line 216
    # ...
}

我收到此警告: Use of uninitialized value $url in pattern match (m//) at ./myScript.pl line 216.

我不明白的是 - 如果next指令没有执行,那么我就匹配了。如果我有匹配$1应该包含一些url字符串。但相反,它是未初始化的。为什么?

1 个答案:

答案 0 :(得分:4)

你混淆了两件事。 '匹配'是布尔测试。这段文字是否与特定模式匹配。

if ($urlCandidate !~ $URL_PATTERN)

测试此变量是否(不)与定义的模式一样。

$1是一个捕获组,它用于从模式中选择事物。通常,这是'括号内的东西'。

因此,如果您将网址格式转换为:

qr/(http.*html)/

然后定义$1

就个人而言,我不喜欢整个$1语法,并倾向于直接从模式中分配变量。

E.g:

my ( $capture ) = ( $string =~ m/Content: (\w+)/ );

您仍然可以在布尔表达式中使用它(如果测试最后一个表达式):

if ( my ( $capture ) = m/pattern_match: (\w+)/ ) {
    print $capture;
}

或者:

if ( $string =~ m/(?<capture>\w+)/ ) {
    print Dumper \%+;
    print $+{capture},"\n";
}

或者,有一组匹配变量:

$`, $&, $'
  

$&安培;   与上一次成功模式匹配的字符串匹配(不计算当前BLOCK包含的BLOCK或eval()中隐藏的任何匹配项。)

     

$`   在上一次成功模式匹配的匹配之前的字符串,不计算隐藏在当前BLOCK包围的BLOCK或eval中的任何匹配。

     

$”   字符串跟随上次成功模式匹配的任何内容(不计算BLOCK中隐藏的任何匹配或当前BLOCK包含的eval())。

但是这些都有一个警告:

http://perldoc.perl.org/perlvar.html#Performance-issues

  

传统上在Perl中,任何使用三个变量$`,$&amp;或者$'(或者他们使用英语等价物)在代码中的任何地方,导致所有后续成功的模式匹配复制匹配的字符串,以防代码随后访问其中一个变量。这对整个程序造成了相当大的性能损失,因此一般不鼓励使用这些变量。