我想用动态创建的regxp创建子例程。以下是我到目前为止的情况:
#!/usr/bin/perl
use strict;
my $var = 1234567890;
foreach (1 .. 9){
&theSub($_);
}
sub theSub {
my $int = @_;
my $var2 = $var =~ m/(??{$int})/;
print "$var2\n";
}
看起来它会起作用,但似乎一旦正则表达式中的$ int首次得到评估,就会永远存在。
无论如何都要做类似的事情,但每次调用sub时正则表达式会选择新的参数吗?
答案 0 :(得分:16)
修复代码的最简单方法是在my
周围添加括号,然后删除??{
。这是固定的程序:
#!/usr/bin/perl
use strict;
my $var = 1234567890;
foreach (1 .. 9){
theSub($_);
}
sub theSub {
my($int) = @_;
my($var2) = $var =~ m/($int)/;
print "$var2\n";
}
代码中有问题的一行是my $int = @_
,相当于my $int = 1
,因为它在标量上下文中评估了@_
,产生了{{1}中的元素数量}。要获取sub的第一个参数,请使用@_
来评估列表上下文中的my($int) = @_;
,或使用@_
获取第一个元素,或使用{{1获取+删除第一个元素}}
my $int = $_[0];
行中存在类似的问题,您还需要括号来评估列表上下文中的正则表达式匹配,产生my $int = shift;
列表,并指定my $var2 =
你试图使用的构造($1, $2, ...)
产生与你想要的相反的效果:(在做其他事情之间)它在第一次用于匹配时编译你的正则表达式。对于包含$var2 = $1
或(??{...})
但未包含$
的正则表达式,Perl会自动为每个匹配重新编译正则表达式,除非指定@
标志(例如??{...}
)。
构造o
表示:使用Perl代码m/$int/o
生成正则表达式,并在此处插入该正则表达式。要获取更多信息,请在http://perldoc.perl.org/perlre.html上搜索(??{...})
。它在您的示例中不起作用的原因是您需要额外的一层括号来捕获...
,但即使使用??{
也不会有效,因为{{1} }具有未记录的属性:它在第一次使用正则表达式进行匹配时强制编译其参数,因此$1
始终匹配my ($var2) = $var =~ m/((??{$int}))/
。
答案 1 :(得分:3)
my $int = @_;
这将为您提供参数计数,在您的情况下始终为“1”。
我想你想要
my $int = shift;
答案 2 :(得分:3)
要动态地将正则表达式传递给函数,而不是在函数中动态构建它,请使用qr //.
#!/usr/bin/perl
use strict;
my $var = 1234567890;
foreach (1 .. 9){
&theSub(qr/$int/);
}
sub theSub {
my($regexp) = @_;
my($var2) = ($var =~ $regexp);
print "$var2\n";
}
qr //接受与m //相同的尾随参数:i,m,s和x
答案 3 :(得分:0)
我的$ int是标量上下文,他有($ int)列表上下文,并将$ _ [0]放入$ int。在下文中,只有10个被放入$ int,其余的11到99个被丢失。
my($ int)=(10..99); print $ int; 10