首先,切勿使用以下构造:
my $var = $val if( $some );
根据文档:
注意:使用语句修饰符条件或循环构造(例如,my $x if ...)修改的my、state或our的行为是未定义的。my变量的值可能是undef,任何先前分配的值,或者可能是其他任何值。不要依赖它。未来版本的 perl 可能会做一些与您尝试使用的 Perl 版本不同的事情。这里是龙。
m//
运算符,当在列表上下文/g
中指定修饰符时,它返回与正则表达式中的任何捕获括号匹配的子字符串的列表。因此,正如@Сухой27 在上面的评论中所说,您应该使用:
my ($some) = $str =~ m/...(...).../g;
举个简单的例子:
use strict;
use warnings;
my $u="undefined";
my $str = q{some="string" another="one"};
#will match
my ($m1) = $str =~ m/some="(.*?)"/g;
print 'm1=', $m1 // $u, '= $1=', $1 // $u, "=\n";
#will NOT match
my ($m2) = $str =~ m/nothere="(.*?)"/g;
print 'm2=', $m2 // $u, '= $1=', $1 // $u, "=\n";
#will match another
my ($m3) = $str =~ m/another="(.*?)"/g;
print 'm3=', $m3 // $u, '= $1=', $1 // $u, "=\n";
印刷:
m1=string= $1=string=
m2=undefined= $1=string= #the $1 hold previously matched value
m3=one= $1=one=
如您所见,$1
匹配不成功时的剩余部分。文档说:
这些特殊变量,如 %+ 散列和编号匹配变量($1
、$2
、$3
等)是动态范围的,直到封闭块结束或直到下一个成功匹配,以先到者为准。(请参阅 perlsyn 中的复合语句。)
注意:Perl 中失败的匹配不会重置匹配变量,这使得编写测试一系列更具体情况并记住最佳匹配的代码变得更容易。
因此,如果您不想$1
定义,您可以将匹配部分包含在一个块中,例如:
use strict
use warnings;
my $u="undefined";
my $str = q{some="string" another="one"};
my($m1,$m2,$m3);
{($m1) = $str =~ m/some="(.*?)"/g;}
print 'm1=', $m1 // $u, '= $1=', $1 // $u, "=\n";
{($m2) = $str =~ m/nothere="(.*?)"/g;}
print 'm2=', $m2 // $u, '= $1=', $1 // $u, "=\n";
{($m3) = $str =~ m/another="(.*?)"/g;}
print 'm3=', $m3 // $u, '= $1=', $1 // $u, "=\n";
打印什么
m1=string= $1=undefined=
m2=undefined= $1=undefined=
m3=one= $1=undefined=
PS:我不是 Perl 大师,也许其他人会扩展/纠正这个答案。