2014-12-04 80 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"; 
相關問題