在这个Perl示例中,$ {$ exp},$ - [$ exp]和$ + [$ exp]的作用是什么,它提取正则表达式匹配的位置?

时间:2015-05-13 10:30:51

标签: regex perl

$#- and $-[$exp]

的含义是什么?
$x = "Mmm...donut, thought Homer";

$x =~ /^(Mmm|Yech)\.\.\.(donut|peas)/; # matches

foreach $exp (1..$#-)
{
    print "Match $exp: '${$exp}' at position ($-[$exp],$+[$exp])\n";
}

输出:

Match 1: 'Mmm' at position (0,3)
Match 2: 'donut' at position (6,11)

1 个答案:

答案 0 :(得分:1)

在Perl中,$#ary是数组@ary的最后一个元素的索引。因此,$#-是数组@-的最后一个元素的索引:

  

$-[0]是上次成功比赛开始的偏移量。 $-[n]是由第n个子模式匹配的子字符串的开头的偏移量,如果子模式不匹配则为undef。

因此,1 .. $#-@-的一系列索引。

${$exp}是一种象征性的解除引用。如果$exp为1,则会显示$1的文字。我不会在实际代码中使用它。相反,使用@+来提取子字符串。

此外,虽然您知道此示例将匹配,但在现实生活中, 从不 使用数字变量而不确保上一次匹配成功。

#!/usr/bin/env perl

use strict;
use warnings;

my $x = "Mmm...donut, thought Homer";

if ( $x =~ /^(Mmm|Yech) [.]{3} (donut|peas)/x ) {
    for my $i (1 .. $#-) {
        my ($s, $e) = ($-[$i], $+[$i]);
        printf(
            "Match %d: '%s' at position [%d,%d)\n",
            $i, substr($x, $s, $e - $s), $s, $e
        );
    }
}

输出:

Match 1: 'Mmm' at position [0,3)
Match 2: 'donut' at position [6,11)

请注意:

  

$+[1]是过去$1结束的偏移量,$+[2]过去$2结束的偏移量,依此类推。您可以使用$#+来确定上次成功匹配中有多少个子组。

因此,滥用上述半闭区间符号。