s/\G /0/g 是什么意思?

6

我正在使用Perl中的正则表达式。其中一件事情让我疑惑:

my $n = "   49 here";
$n =~ s/\G /0/g;
print $n;

这将得到:

00049 here

我知道s修饰符(单行)。我也了解g修饰符(全局,它跟踪最后一次匹配的位置)。我知道正则表达式用零替换某些内容,但我不明白\G和其后面的空格是什么意思(如果没有\G后面的空格,结果是:0 49 here)。


\G 被称为 G 锚点构造。它意味着它必须匹配上次成功匹配结束的地方。 - user557597
2
我知道s修饰符(单行)。我认为你把它和替换运算符混淆了。s修饰符:/foo/s,替换运算符:s/foo/bar/ - ThisSuitIsBlackNot
是的,确实,感谢您澄清这一点! - Agnaroc
2个回答

5

\G 被称为 G-Anchor 结构。它意味着它必须匹配上一次成功匹配的位置。在任何正则表达式开始之前,\G(实际上是一个标志)是 true,所以它会从 true 开始,然后寻找空格,找到它后仍然是 true,继续寻找下一个空格,以此类推... 当它找不到空格时,\G 标志变为 false 并保持这种状态(在这种情况下)。

如果没有它,它将在字符串中任何地方寻找空格,而不仅仅是在开头。

$ perl -E'my $n = "   49 here"; $n =~ s/\G /0/g; say $n'
00049 here

$ perl -E'my $n = "   49 here"; $n =~ s/ /0/g; say $n'
000490here

/\G/g 只会在字符串开头匹配(空),因为Perl不会返回完全相同的匹配(定义为具有相同的起始位置和相同的长度)两次。这就是为什么它会在那里添加一个 0 并停止以下操作:

$ perl -E'my $n = "   49 here"; $n =~ s/\G/0/g; say $n'
0   49 here

在Perl中,最后一次匹配结束的位置与被匹配的变量相关联(而不是操作符)。可以使用pos函数观察和更改它。\G标志留在变量中,而不是正则表达式中。由于它与被匹配的变量相关联,在随后应用另一个正则表达式时,\G将从上一次匹配结束的位置开始。
$ perl -E'my $n = "abcdefabc"; $n =~ /def/g; $n =~ s/\Gabc/ABC/; say $n'
abcdefABC

2
我认为这里并没有被误用 - 目的似乎是将行首的空格填充数字转换为零填充数字,因此在字符串初始空格后不匹配是有意的。 - psmears
啊,我看到你在我写评论的时候更新了答案 :) - psmears
@psmears - 当然这可能是意图,但谁知道呢。我知道另外20种在Perl中实现它的方法。 - user557597
1
这实际上不是一个标志,perl -E'my $n = "abcdefabc"; $n =~ s/def\Gabc/!!!/; say $n'perl -E'my $n = "abcdefabc"; pos($n)=6; $n =~ s/def\Gabc/!!!/; say $n' - ikegami
@ikegami - 我认为每个非全局匹配上下文后,最后一次的匹配位置都会被重置。说"标志(flag)"比在命中\G构造点时要容易些,当前位置必须等于之前的位置。在PHP中,我猜最初\G是指字符串的开头,但也不确定。 - user557597

2
在Perl中,\G断言匹配结束位置或第一次匹配的字符串开始位置。
这就是为什么在开头的空格和之后的所有空格都被替换为0,但在49之后的空格没有变化。 RegEx Demo(使用PCRE而不是Perl,但在该引擎中\G意味着相同的事情)

我理解了,但为什么这个代码: $n =~ s/\G/0/g; 输出结果是:0 49 here 而这个代码: $n =~ s/\G /0/g; 输出结果是:00049 here 请注意,我在这里使用的是Perl(请注意第一个代码中的空格) 我看过你的正则表达式演示,但那仍然无法解释为什么需要空格 :( - Agnaroc
第дёҖдёӘsжҳҜ жӣҝжҚў е‘Ҫд»ӨпјҢ\G жҳҜеёҰжңү 0 жӣҝжҚўзҡ„жЁЎејҸгҖӮg д»ЈиЎЁе…ЁеұҖгҖӮ - anubhava
但是空格意味着什么? - Agnaroc
1
@ikegami:没错,但是正则表达式在很大程度上是兼容的,因此才有这个名字 :) - psmears
类似但不完全相同。已修正回答。此评论将自行销毁。 - ikegami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接