我认为这个问题是重复的,但搜索对我没有帮助。
my $pattern = "javascript:window.open\('([^']+)'\);";
$mech->content =~ m/($pattern)/;
print $1;
我希望在正则表达式中有一个外部$pattern
。我怎样才能做到这一点?当前的一个返回:
在main.pm第20行打印时使用未初始化的值$ 1。
答案 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未定义,因为您通过在模式周围包裹第二组括号来创建嵌套匹配组。如果没有与您的模式匹配,它也将是未定义的。