我对 Perl 比较陌生,通过最近的学习,我最终得到了一些脚本并偶然发现了这个正则表达式
$+
表示最后一个搜索模式匹配的最后一个括号。如果您不知道一组替代模式中的哪一个匹配,这非常有用。例如:
/Version: (.*)|Revision: (.*)/` && `($rev = $+);
听起来很有趣,但我不明白它实际上是做什么的,有人可以帮助我理解它的用法吗,
我还发现了一些例子,如下所示,
“
$<digit>
正则表达式括号捕获持有者。”
正则表达式可以具有捕获组,在成功匹配后,捕获组包含模式该部分的匹配子字符串:
/Version: (.*)|Revision: (.*)/
# $1 $2
这些从左到右依次为
$1
、$2
、...。有时,我们可能想访问最后一次成功的捕获。例如:
"Version: v123" → "v123"
"Revision: v678" → "v678"
所以我们要么需要
$1
,要么需要$2
,它们不会同时被填满。我们可以做:
/Version: (.*)|Revision: (.*)/ and $rev = ($1 // $2)
它使用
//
定义的或运算符。或者我们可以使用 $+
来引用最近成功的捕获。你可以把它想象成$-1
:最后一个捕获组(只不过它不是源代码中的最后一个,而是时间上最新的)。
在这个简单的例子中,使用
$+
可能有意义,但我从未真正使用过它。更好的解决方法包括:
使用命名捕获,可通过
%+
哈希访问:
/Version: (?<rev>.*)|Revision: (?<rev>.*)/ and $rev = $+{rev}
使用
(?| ... | ... )
结构重置编号。这打破了捕获组从左到右的正常编号,而是对每个替代项进行独立编号:
/(?|Version: (.*)|Revision: (.*))/ and $rev = $1
# $1 $1
$<digit>
保存捕获缓冲区信息。
正则表达式 -
Version:\
( .* ) # (1)
|
Revision:\
( .* ) # (2)
代码 -
if ( $str =~ /Version: (.*)|Revision: (.*)/ )
{
if ( defined $1 ) {
$ver = $1;
}
elsif ( defined $2 ) {
$rev = $2;
}
}
Perl v5.10 在模式中添加了分支重置运算符,因此您不必考虑哪个交替匹配。在此示例中,两个捕获组都是
$1
:
use v5.10;
while( <DATA> ) {
if( /(?|Version: (.*)|Revision: (.*))/ ) {
say $1;
}
}
__DATA__
Version: 1.2.3
Revision: 4.6.8
对于像这样的简单示例,您可以提取前缀。这无需 v5.10 功能即可工作:
while( <DATA> ) {
if( /(?:Version|Revision): (.*)/ ) {
print $1, "\n";
}
}