Regex Perl正则表达式和捕获组

Regex Perl正则表达式和捕获组,regex,perl,Regex,Perl,以下打印件ac | a | bbb | c #!/usr/bin/env perl use strict; use warnings; # use re 'debug'; my $str = 'aacbbbcac'; if ($str =~ m/((a+)?(b+)?(c))*/) { print "$1 | $2 | $3 | $4\n"; } 似乎失败的匹配不会重置捕获的组变量。

以下打印件
ac | a | bbb | c

    #!/usr/bin/env perl
    use strict;
    use warnings;
    # use re 'debug';
    
    my $str = 'aacbbbcac';
    
    if ($str =~ m/((a+)?(b+)?(c))*/) {
       print "$1 | $2 | $3 | $4\n";
    }
似乎失败的匹配不会重置捕获的组变量。 我错过了什么

似乎失败的匹配不会重置捕获的组变量

那里没有失败的匹配。您的正则表达式与字符串匹配得很好。虽然在某些重复中内部组有一些失败的匹配。每个匹配的组可能会被为该特定组找到的下一个匹配项覆盖,或者如果该组在当前重复中不匹配,则会保留上一个匹配项的值

让我们看看正则表达式匹配是如何进行的:

  • 第一个
    (a+)(b+)(c)
    匹配
    aac
    。由于
    (b+)
    是可选的,因此将不匹配。在此阶段,每个捕获组包含以下部分:

    • $1
      包含整个匹配-
      aac
    • $2
      包含
      (a+)
      部分-
      aa
    • $3
      包含
      (b+)
      部分-
      null
    • $4
      包含
      (c)
      部分-
      c
  • 因为还有一些字符串需要匹配-
    bbbcac
    。继续-
    (a+)(b+)(c)
    匹配-
    bbbc
    。由于
    (a+)?
    是可选的,因此将不匹配

    • $1
      包含整个匹配-
      bbbc
      。覆盖
      $1
    • $2
      不匹配。因此,它将包含以前匹配的文本-
      aa
    • $3
      这次匹配。它包含-
      bbb
    • $4
      匹配
      c
  • 同样,
    (a+)(b+)(c)
    将继续匹配最后一部分-
    ac

    • $1
      包含整个匹配-
      ac
    • $2
      这次与
      a
      匹配。覆盖
      $2
      中的上一个值。它现在包含-
      a
    • $3
      这次不匹配,因为没有
      (b+)?
      部件。它将与之前的匹配相同-
      bbb
    • $4
      匹配
      c
      。覆盖上一个匹配的值。它现在包含-
      c
现在,字符串中没有可匹配的内容。所有捕获组的最终值为:

  • $1
    -
    ac
  • $2
    -
    a
  • $3
    -
    bbb
  • $4
    -
    c

这似乎很奇怪,但却是“预期”的行为。以下是文档中的引用:

注意:Perl中失败的匹配不会重置匹配变量,这使得编写测试一系列更具体情况并记住最佳匹配的代码变得更容易


对于括号分组,
/(\d+)/
这表示使用
\1\2…
\g{1}\g{2}
。在替换正则表达式部分中使用
$1或$2…
将导致如下错误:在模式中找到标量

# Example to turn a css href to local css.
# Transforms <link href="http://..." into <link href="css/..."

# ... inside a loop ...

my $localcss = $_; # one line from the file
$localcss =~ s/href.+\/([^\/]+\.css")/href="css\/\1/g ;
#将css href转换为本地css的示例。

#转换您期望的输出是什么?@ikegami我知道,这不是我的模式,我在G+Perl社区上遇到了这个问题,并对此感到好奇。此外,失败的匹配不会重置捕获变量<代码>perl-E's“a”=~/(.)/;“b”=~/(…)/;比如说1美元除此之外,这不是一个答案,而是什么?上面所有$1$2的使用都会在Perl标量中崩溃。谢谢你的戳。你在哪里看到的
\1
用于模式内部的反向引用,
$1
是包含组1值的变量,它用于替换部分或正则表达式外部,它们是两个不同的概念。我来到本页是因为我需要在替换内部的反向引用。其他人会喜欢的。感谢您的关注。链接文档清楚地告诉您不要在您的情况下使用
\1
,它只是有时仍然有效:“这是因为在PerlThink中,s///的右侧是一个双引号字符串。\1在通常的双引号字符串中表示控件-a.[…]您不能通过说\{1}000来消除歧义,而您可以用${1}000."