我想将reg-ex的单个捕获作为标量传递给子程序,我该怎样做呢?这是一个例子:
sub myfunc($)
{
my ($value)=@_;
# Do something with $value...
}
# This is the data we want to parse
my $some_var='value: 12345'; # For example
# We want to extract the value '12345' from $some_var
# and pass it to the myfunc subroutine as a scalar
# Attempt #1: This doesn't work
myfunc($some_var=~/value: (\d+)/);
# Attempt #2: This does work, but seems overly complicated
myfunc(join('',$some_var=~/value: (\d+)/));
有没有比尝试#2更好的方法?
更新
Oesor的回答完全给出了我要求的内容,以避免调用join
:
myfunc(($some_var=~/value: (\d+)/)[0]);
答案 0 :(得分:7)
是的,还有更好的方法!使用$ capture组变量。
$some_var =~ /value: (\d+)/;
myfunc($1);
你也可以链接和嵌套它们:
$some_var =~ /(\w+): (\d+)/;
# now $1 eq "value" and $2 eq "12345"
# and
$some_var =~ /((\w+): (\d+))/;
# now $1 eq "value: 12345" and $2 eq "value" and $3 eq "12345"
答案 1 :(得分:5)
一般来说,答案是不使用原型。您可以通过如何处理参数列表来使用一个值,而不是在其上强加上下文:
sub myfunc {
my ($val) = @_;
say $val;
};
my $var = 'value: 12345';
myfunc($var =~ /value: (\d+)/);
myfunc(qw/1 2 3 4 5/)
发射:
12345
1
您可以使用列表切片来获取列表的子集(在这种情况下,第一个项目),然后对其施加标量上下文:
sub myfunc($) {
my ($val) = @_;
say $val;
};
my $var = 'value: 12345';
myfunc(($var =~ /value: (\d+)/)[0]);
发射:
12345
这允许正则表达式运算符在列表上下文中操作并返回结果列表而不是强制标量上下文,该上下文将返回结果数,从单个元素列表中切片,然后在第一个元素列表上施加标量上下文列表中的项目。
答案 2 :(得分:4)
如果您想在无条件函数调用
之前首先测试匹配是否成功sub myfunc
{
my ($value)=@_;
}
my $some_var='value: 12345'; # For example
myfunc($1) if $some_var =~ /value: (\d+)/;
# or
if (my ($var) = $some_var =~ /value: (\d+)/) {
myfunc($var);
}
答案 3 :(得分:2)
通过更改原型来强制数组上下文:
sub myfunc(@) {
# Do something
}
或者更好的是,将它们全部删除:
sub myfunc {
# Do something
}