【问题标题】:What does s/\G /0/g mean?s/\G /0/g 是什么意思?
【发布时间】:2015-06-06 01:45:17
【问题描述】:

我在 Perl 中使用正则表达式。我遇到的一件事:

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

这给出了:

00049 here

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

【问题讨论】:

  • \G 被称为 G-Anchor 构造。这意味着它必须匹配上一次成功匹配的结束位置。
  • “我知道s 修饰符(单行)。”我认为您将其与替换运算符混淆了。 s 修饰符:/foo/s 替换运算符:s/foo/bar/
  • 是的,感谢您的澄清!

标签: regex perl


【解决方案1】:

\G 被称为 G-Anchor 构造。这意味着它必须匹配上一次成功匹配结束的位置。在任何正则表达式开始之前,\G(真的是一个标志)是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 只会在字符串的开头匹配(无)1 次,因为 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

【讨论】:

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

在 Perl 中,\G 在前一个匹配的结尾或第一个匹配的字符串的开头断言位置。

这就是为什么开头的空格和之后的所有空格都被0 替换,但49 之后的空格保持不变。

RegEx Demo(使用 PCRE 而不是 Perl,但 \G 在该引擎中的含义相同)

【讨论】:

  • 我明白但为什么会这样:$n =~ s/\G/0/g;将此作为输出: 0 49 here While this: $n =~ s/\G /0/g;将此作为输出: 00049 here 请注意,我在这里使用 perl(注意第一个代码中的空格)我看到了您的正则表达式演示,但这仍然不能解释为什么需要空格:(
  • 第一个 s 用于 substitute 命令,\G 是用0 替换的模式。 g 用于全球。
  • 但是空格是什么意思?
  • @ikegami:没错,但 RE 很大程度上兼容,因此得名:)
  • 类似,但不一样。修正了答案。此评论将自毁。
猜你喜欢
  • 2021-07-01
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 2013-03-24
  • 1970-01-01
  • 2011-08-28
  • 1970-01-01
  • 2019-06-07
相关资源
最近更新 更多