【发布时间】:2016-10-04 15:51:13
【问题描述】:
根据perlvar:
与正则表达式相关的变量
这些变量是只读的 并且是动态范围的,除非我们另有说明。动态性质 的正则表达式变量意味着它们的值是有限的 到他们所在的街区。
再往下:
传统上,在 Perl 中,任何使用三个变量中的任何一个
$`,$&或$'代码中的任何位置,导致 所有后续成功的模式匹配以复制 匹配的字符串,以防代码随后访问其中之一 那些变量。
从文档中阅读了该部分的其余部分后,我仍然错过了一些信息,例如:
-
为什么首先要制作副本?
我想我知道这个问题的答案:从上一条声明
"in case the code might subsequently access one of those variables"中可以清楚地看出这一点。 所以在我的理解中:my $s = "Hello world"; $s =~ s/Hello //; say $';这仍然会打印
world,因为在修改$s之前已制作了副本。 -
为什么要复制整个字符串?
在前面的示例中,只复制字符串的尾部就足够了,因为只使用了
$'(我们没有使用$`或$&)。那么为什么要复制整个字符串呢? -
最后:既然是
"all subsequent"而不是"all subsequent matches in that block",我想确认一下:my $s = "no\n yesHello world"; { $s =~ /yes/ and say $'; # Note the use of $' } $s = '12' x 1_000_000; my $n = () = $s =~ /2/g; say "Found $n matches";在这种情况下,(因为
$'仅用于内部范围)不会与$s =~ /2/g中的一百万个成功匹配相关的复制? (假设我没有在外部范围内提及$`、$&和$')
注意:
-
问题假设 perl 版本低于 5.18。 根据perlvar:
从 Perl 5.18.0 开始,perl 开始记录每个 三个变量分开,并且只复制了那部分 需要字符串
在 Perl 5.20.0 中,默认启用了新的写时复制系统, 最终解决了这三个变量的所有性能问题, 并让它们在任何地方都可以安全使用。
-
我只是出于好奇才问这个问题。我不打算在我的代码中实际使用任何这些变量,因为我希望我的程序也能有效地为早期的 perl 版本(
此外,如手册中所述,可以使用
$+[0]和$-[0](在 perl 5.6 版中引入。我自己使用 perl 5.22 版)轻松模拟它们(没有隐式复制和性能损失) .请参阅perlvar 了解更多信息。
【问题讨论】:
-
在 5.20 之前,您可以使用 /p 或捕获。
标签: perl