什么时候是\正则表达式中有用的应用程序?

时间:2014-02-23 17:28:25

标签: regex perl

我不清楚\G运营商的使用/需求 我读了perldoc

  

使用\ G锚点在同一个字符串中开始下一个匹配   最后一场比赛停止了。

我真的不明白这句话。当我们使用\g时,我们通常会在最后一场比赛后移动到角色 如示例所示:

$_ = "1122a44";  
my @pairs = m/(\d\d)/g;   # qw( 11 22 44 )  

然后它说:

  

如果使用\ G锚点,则在22之后强制匹配   a:

$_ = "1122a44";
my @pairs = m/\G(\d\d)/g;
  

正则表达式无法匹配,因为它没有   找到一个数字,所以下一个匹配失败,匹配运算符返回   它已经找到的对

我也不明白这一点。 “如果您使用\ G锚点,则在22之后强制匹配以开始。”但没有\ G,无论如何都会在a进行匹配吗?那句话的含义是什么? 我看到在这个例子中,打印的唯一对是11和22.所以44没有尝试过。

该示例还显示使用c选项使其在之后的索引44

老实说,从这些方面来看,我无法理解这个操作符的用处以及何时应用它。
有人可以帮助我理解这一点,或许有一个有意义的例子吗?

更新
我想我不理解这个关键句:

  

如果使用\ G锚点,则在22之后强制匹配   a。正则表达式无法匹配,因为它没有   找到一个数字,所以下一个匹配失败,匹配运算符返回   它已经找到的对。

这似乎意味着当匹配失败时,正则表达式不会进行进一步的尝试,并且与答案中的示例一致

另外:

  

匹配在字母a失败后,perl重置pos()和下一个   相同字符串的匹配从头开始。

3 个答案:

答案 0 :(得分:16)

\ G是一个锚;它表示强制开始比赛的位置。当\ G存在时,它不能在字符串中的任意后续点开始匹配;当\ G缺席时,它可以。

将字符串解析为离散部分非常有用,您不希望跳过其他内容。例如:

my $string = " a 1 # ";
while () {
    if ( $string =~ /\G\s+/gc ) {
        print "whitespace\n";
    }
    elsif ( $string =~ /\G[0-9]+/gc ) {
        print "integer\n";
    }
    elsif ( $string =~ /\G\w+/gc ) {
        print "word\n";
    }
    else {
        print "done\n";
        last;
    }
}

使用\ G输出:

whitespace
word
whitespace
integer
whitespace
done

whitespace
whitespace
whitespace
whitespace
done

请注意,我正在使用标量上下文/ g匹配进行演示,但是\ G同样适用于列表上下文/ g匹配,实际上上面的代码可以简单地修改为使用它:

my $string = " a 1 # ";
my @matches = $string =~ /\G(?:(\s+)|([0-9]+)|(\w+))/g;
while ( my ($whitespace, $integer, $word) = splice @matches, 0, 3 ) {
    if ( defined $whitespace ) {
        print "whitespace\n";
    }
    elsif ( defined $integer ) {
        print "integer\n";
    }
    elsif ( defined $word ) {
        print "word\n";
    }
}

答案 1 :(得分:11)

  

但没有\ G,无论如何都会尝试匹配吗?

如果没有\G,则不会限制它在那里开始匹配。它会尝试,但如果需要,它会尝试稍后启动。您可以将每个模式视为前面有隐含的\G.*?

添加\G,意思变得明显。

$_ = "1122a44";  
my @pairs = m/\G     (\d\d)/xg;   # qw( 11 22 ) 
my @pairs = m/\G .*? (\d\d)/xg;   # qw( 11 22 44 )
my @pairs = m/       (\d\d)/xg;   # qw( 11 22 44 )
  

老实说,从这些方面来看,我无法理解这个操作符的用处以及何时应用它。

正如您所看到的,通过添加\G可以获得不同的结果,因此实用性可以获得您想要的效果。

答案 2 :(得分:2)

有趣的答案和很多都是有效的我猜,但我也可以猜测仍然没有解释很多。

\ G'部队'下一场比赛将在最后一场比赛结束时发生。

基本上:

$str="1122a44";
while($str=~m/\G(\d\d)/g) {
#code
}

第一场比赛=" 11" 第二场比赛是强制在22开始,是的,那是\ d \ d,所以结果是" 22" 第三次尝试'是强行从" a"开始,但那不是\ d \ d,所以它失败了。