2

以下是 Perl 可以做的许多很酷的事情之一

my ($tmp) = ($_=~ /^>(.*)/);

它在循环的当前行中找到模式 ^>.*,并将括号中的内容存储在 $tmp 变量中。

我很好奇的是这种语法背后的概念。这如何以及为什么(在什么前提下)起作用?我的理解是片段 $_=~ /^>(.*)/ 是布尔上下文,但括号将其呈现为列表上下文?但是为什么只有匹配模式中括号中的内容存储在变量中?!

这是我必须“记住”的变量赋值的某种特殊情况,还是可以完美解释?如果是这样,这个功能叫什么(名称如“autovivifacation?”)

4

3 回答 3

5

有两种赋值运算符:列表赋值和标量赋值。选择是根据“ =”的 LHS 确定的。(这里详细介绍了这两个运算符。)


在这种情况下,使用列表赋值运算符。列表赋值运算符在列表上下文中计算其两个操作数。

那么$_=~ /^>(.*)/在列表上下文中做什么呢?引用perlop

如果/g未使用该选项,则m//在列表上下文中返回由模式中括号匹配的子表达式组成的列表,即 ( $1, $2, $3...) [...] 当模式中没有括号时,返回价值是(1)成功的清单。有或没有括号,失败时返回一个空列表。

换句话说,

my ($match) = $_ =~ /^>(.*)/;

相当于

my $match;
if ($_ =~ /^>(.*)/) {
    $match = $1;
} else {
    $match = undef;
}

如果省略括号 ( my $tmp = ...;),则将使用标量赋值。标量赋值运算符在标量上下文中计算其两个操作数。

那么$_=~ /^>(.*)/在标量上下文中做什么呢?引用perlop

如果成功则返回 true,如果失败则返回 false。

换句话说,

my $matched = $_ =~ /^>(.*)/;

相当于

my $matched;
if ($_ =~ /^>(.*)/) {
    $matched = 1;   # !!1 if you want to be picky.
} else {
    $matched = 0;   # !!0 if you want to be picky.
}
于 2012-04-26T21:06:54.300 回答
2

搜索模式中的括号使它成为一个“组”。返回的是$_ =~ /regex/所有匹配组的数组,因此my ($tmp)将第一个组抓取到 $tmp 中。

于 2012-04-26T21:03:31.870 回答
1

All operations in perl have a return value, including assignment. Thats why you can do $a=$b=1 and set $a to the result of $b=1.

You can use =~ in a boolean (well, scalar) context, but that's just because it returns an empty list / undef if there's no match, and that evaluates to false. Calling it in an array context returns an array, just like other context-sensitive functions can do using the wantarray method to determine context.

于 2012-04-26T21:08:14.933 回答