2014-12-04 86 views
1

我有一个子程序,需要输入一个字符串中的位置,并应返回在该位置找到的单词。例如:如何获取Perl正则表达式匹配变量的值与索引存储在另一个变量?

use warnings; 
use strict; 

my $num=2; 
my $val=getMatch($num); 

sub getMatch { 
    my ($num)[email protected]_; 

    my $str='a b c'; 
    $str=~ /(\S+)\s(\S+)/; 

    my $res; 
    eval "$res=\$$num"; 
    return $res 
} 

但是这给了错误:

Use of uninitialized value $res in concatenation (.) or string at ./p.pl line 16. 

(我试图返回$i其中i是存储在另一个变量的值。)

+0

好像我忘了把一个斜杠'$ res'的面前:'EVAL“\ $水库= \ $$ num“'..但也许有更简单的方法来做到这一点? – 2014-12-04 08:50:00

回答

3

我会怎么做:

my $num=2; 
my $val=getMatch($num); 
say $val; 
sub getMatch { 
    my ($num)[email protected]_; 
    my $str='a b c'; 
    my @res = $str =~ /(\S+)\s(\S+)/; 
    return $res[$num-1]; 
} 

输出:

b 
2

您可以使用@+@-特殊变量,在perlvar记录,像这样:

sub getMatch { 
    my ($num)[email protected]_; 

    my $str='a b c'; 
    $str=~ /(\S+)\s(\S+)/; 

    return substr($str, $-[$num], $+[$num] - $-[$num]); 
} 
print getMatch(1), "\n"; 
print getMatch(2), "\n"; 

或者你可以调整你的正则表达式是这样的:

sub getMatch { 
    my $num = shift() - 1; 
    my $str='a b c'; 
    $str=~ /(?:\S+\s){$num}(\S+)/; 

    return $1; 
} 
print getMatch(1), "\n"; 
print getMatch(2), "\n"; 

...这具有仅产生一个捕获组的优点。

另一种选择是只拆空间:

sub getMatch { 
    my ($num)[email protected]_; 
    my $str='a b c'; 
    return (split /\s/, $str)[$num-1]; 
} 

print getMatch(1), "\n"; 
print getMatch(2), "\n"; 

...但是,这最后的解决方案是什么,它将匹配更加宽容的;它并不明确需要两个或更多由空格分隔的非空间项目。如果3被传入,它将返回'c'。

最后一个产生类似于拆分版本的结果,但使用正则表达式。我可能会更喜欢分裂,因为它更简单,但我提供这个只是教诲:

sub getMatch { 
    my ($num)[email protected]_; 
    my $str='a b c'; 
    return ($str =~ m/(\S+)(?=\s|$)/g)[$num-1]; 
} 

print getMatch(1), "\n"; 
print getMatch(2), "\n"; 
相关问题