2017-06-14 67 views
1

我得到了一些行为,我不理解的Perl:

>>> my @words = ('hello', 'there'); 
>>> $words[0] =~ /(el)/; print $1; 
el 
>>> $words[1] =~ /(el)/; print $1; 
undef 

,但在一个循环:

>>> my @words = ('hello', 'there'); 
>>> foreach my $word (@words){ 
>>> $word =~ /(el)/; 
>>> print "$1\n"; 
>>> } 
el 
el 

这是怎么回事?以及如何我,在循环中,得到$ 1是不确定的,当它没有在最近的正则表达式匹配,所以这样的事情会工作:

foreach my $word (@words) { 
    $word =~ /(el)/; 
    if ($1) { 
     print "$word matched\n"; 
    } else { 
     print "$word did not match\n"; 
    } 
} 

回答

1

循环没有什么特别之处。

use strict; 
use warnings; 
use feature qw(say); 

my @words = ('hello', 'there'); 
$words[0] =~ /(el)/; say $1 // "[undef]"; 
$words[1] =~ /(el)/; say $1 // "[undef]"; 

my @words = ('hello', 'there'); 
foreach my $word (@words){ 
    $word =~ /(el)/; 
    say $1 // "[undef]"; 
} 

输出:

el 
el 
el 
el 

$1和朋友只改变了一个成功的匹配,所以要

for my $word (@words) { 
    if ($word =~ /el/) { 
     print "$word matched\n"; 
    } else { 
     print "$word did not match\n"; 
    } 
} 
+0

我使用的逻辑是有点不仅仅是印刷更复杂比赛。这是我用来试图了解发生了什么的简化情况。有什么办法可以做我想做的事吗?即每当我得到一个匹配时设置'$ 1','$ 2'(或别的东西),如果我没有得到匹配,每次迭代都将它们设置为'undef'? – ewok

+1

'my($ capture)= $ word =〜/(el)/'和'my $ capture = $ word =〜/(el)/? $ 1:undef;'设置'$ capture'以你所描述的想要设置'$ 1'的方式。 – ikegami

+0

完美。这是否意味着我可以使用'my @matches = $ word =〜/(list)(of)(match)(patterns)/;'来获取匹配数组? – ewok

0

一种方法是避免特殊编号完全变量,它们在运行之间不会重置。相反,使用一个局部变量,并在每个循环的开始复位:

use warnings; 
use strict; 

my @words = qw(
    one 
    two 
    three 
); 

for my $w (@words){ 
    my $store; 

    if (($store = $w) =~ /(t)/){ 
     print "$store\n"; 
    } 
    else { 
     print "no match\n"; 
    } 
} 

输出:

two 
three 
0

检查匹配的回报:

if ($word =~ /(el)/) { 
    print "$word matched with [$1]\n"; 
} else { 
    print "$word did not match\n"; 
} 

我怀疑你的测试环境在分别运行它们时会做得更多,包括重新设置$1等等。