如何在Perl中将变量用作正则表达式

时间:2010-08-17 13:04:54

标签: regex perl

我认为这个问题是重复的,但搜索对我没有帮助。

my $pattern = "javascript:window.open\('([^']+)'\);";
$mech->content =~ m/($pattern)/;
print $1;

我希望在正则表达式中有一个外部$pattern。我怎样才能做到这一点?当前的一个返回:

  

在main.pm第20行打印时使用未初始化的值$ 1。

5 个答案:

答案 0 :(得分:3)

$1是空的,所以比赛没有成功。我将在我的例子中组成一个常量字符串,我知道它将匹配模式。

使用qr声明正则表达式,而不是简单的字符串。此外,您在$pattern调用括号的open中进行了两次捕获,一次在m运算符中进行捕获,因此您得到两个结果。而不是$1$2等。我更喜欢将结果分配给数组。

my $pattern = qr"javascript:window.open\('([^']+)'\);";
my $content = "javascript:window.open('something');";
my @results = $content =~ m/($pattern)/;
# expression return array
# (
#     q{javascript:window.open('something');'},
#     'something'
# )

答案 1 :(得分:2)

当我将该字符串编译成正则表达式时,如下所示:

my $pattern = "javascript:window.open\('([^']+)'\);";
my $regex   = qr/$pattern/;

我认为我应该得到的是正则表达式:

(?-xism:javascript:window.open('([^']+)');)/

请注意,它正在寻找捕获组而不是'open'结束时的开放式paren。在那个捕获组中,它预期的第一件事是单引号。所以它会匹配

javascript:window.open'fum';

但不是

javascript:window.open('fum');

你需要学习的一件事是,在Perl中,"\(""("是一样的,你只是告诉Perl你想要一个 literal {{ 1}}在字符串中。为了获得持久的逃脱,你需要加倍。

'('

实际上保留文字my $pattern = "javascript:window.open\\('([^']+)'\\);"; my $regex = qr/$pattern/; 并产生:

(

我认为你想要的是什么。

至于你的问题,你应该在使用之前测试匹配的结果。

(?-xism:javascript:window.open\('([^']+)'\);)

更有意义。如果你想要看到它,那么它已经隐含在这个想法中它可能没有价值。也就是说,你可能没有匹配任何东西。在这种情况下,最好放置替代品

if ( $mech->content =~ m/($pattern)/ ) { 
     print $1;
}

但是,我喜欢在同一个声明中抓住我的捕获,如下所示:

$mech->content =~ m/($pattern)/;
print $1 || 'UNDEF!';

围绕my ( $open_arg ) = $mech->content =~ m/($pattern)/; print $open_arg || 'UNDEF!'; 的parens将匹配放入"list context"并返回列表中的捕获。在这里,我只期待一个价值,所以这就是我所提供的。

最后,问题的根本原因之一是您不需要在字符串中指定表达式,以使正则表达式“可移植”。您可以使用perl来预编译表达式。这样,你只关心字符对正则表达式的指示,而不是在将它编译成表达式之前是否保存你的转义。

编译的正则表达式将正确地插入到其他正则表达式中。因此,您将获得一个可移植的表达式,该表达式与字符串一样进行插值 - 并且特别正确地处理可能在字符串中丢失的指令。

$open_arg

就是你所需要的一切。然后你可以像使用它一样使用它。虽然,将parens放在整个事物周围,会返回整个匹配的表达式(而不仅仅是引号之间的内容)。

答案 2 :(得分:1)

匹配模式中不需要括号。它将匹配整个模式并返回$1,我猜这是不匹配的,但我只是在猜测。

$mech->content =~ m/$pattern/;

$mech->content =~ m/(?:$pattern)/;

这些是clustering, non-capturing parentheses

你这样做是正确的。

答案 3 :(得分:1)

已经提供了解决方案,我想指出window.open调用可能包含""中的多个参数,并按逗号分组:< / p>

javascript:window.open("http://www.javascript-coder.com","mywindow","status=1,toolbar=1");

函数名和括号之间可能有空格,所以我会使用稍微不同的正则表达式:

my $pattern = qr{
    javascript:window.open\s*
    \(
    ([^)]+)
    \)
}x;

print $1 if $text =~ /$pattern/;

现在您拥有$1中的所有参数,然后可以使用split /,/, $stuff处理它们,依此类推。

答案 4 :(得分:0)

它会报告未初始化的值,因为未定义$ 1。 $ 1未定义,因为您通过在模式周围包裹第二组括号来创建嵌套匹配组。如果没有与您的模式匹配,它也将是未定义的。