Perl 最后捕获匹配变量

问题描述 投票:0回答:3

我对 Perl 比较陌生,通过最近的学习,我最终得到了一些脚本并偶然发现了这个正则表达式

$+
表示最后一个搜索模式匹配的最后一个括号。如果您不知道一组替代模式中的哪一个匹配,这非常有用。例如:

/Version: (.*)|Revision: (.*)/` && `($rev = $+);

听起来很有趣,但我不明白它实际上是做什么的,有人可以帮助我理解它的用法吗,

我还发现了一些例子,如下所示,

$<digit>
正则表达式括号捕获持有者。”

regex perl
3个回答
5
投票

正则表达式可以具有捕获组,在成功匹配后,捕获组包含模式该部分的匹配子字符串:

/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
    

0
投票

$<digit>
保存捕获缓冲区信息。

正则表达式 -

   Version:\ 
   ( .* )            # (1)
|  
   Revision:\ 
   ( .* )            # (2)

代码 -

if ( $str =~ /Version: (.*)|Revision: (.*)/ )
{
    if ( defined $1 ) {
        $ver = $1;
    }
    elsif ( defined $2 ) {
        $rev = $2;
    }
}

0
投票

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";
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.