【问题标题】:Replace specific capture group instead of entire regex in Perl在 Perl 中替换特定的捕获组而不是整个正则表达式
【发布时间】:2012-08-21 07:13:11
【问题描述】:

我有一个带有捕获组的正则表达式,可以在更广泛的上下文中匹配我想要的内容。然后我将捕获组$1 用于我的需要。这很容易。

但是当我只想用我的替换替换 $1 的内容而不是整个正则表达式时,如何使用带有 s/// 的捕获组?

例如,如果我这样做:

$str =~ s/prefix (something) suffix/42/

prefixsuffix 被删除。相反,我希望将something 替换为42,同时保持prefixsuffix 不变。

【问题讨论】:

    标签: regex perl replace capture-group


    【解决方案1】:

    据我了解,您可以使用不消耗字符的前瞻或后瞻。或者将数据保存在组中,只删除您要查找的内容。例子:

    带前瞻功能:

    s/your_text(?=ahead_text)//;
    

    分组数据:

    s/(your_text)(ahead_text)/$2/;
    

    【讨论】:

      【解决方案2】:

      如果您只需要替换一个捕获,那么将@LAST_MATCH_START@LAST_MATCH_END(与use English;参见perldoc perlvar)与substr 一起使用可能是一个可行的选择:

      use English qw(-no_match_vars);
      $your_string =~ m/aaa (bbb) ccc/;
      substr $your_string, $LAST_MATCH_START[1], $LAST_MATCH_END[1] - $LAST_MATCH_START[1], "new content";
      # replaces "bbb" with "new content"
      

      【讨论】:

      • 匿名投票者请解释他的投票吗?谢谢。
      【解决方案3】:

      这是一个老问题,但我发现下面更容易将以>something 开头的行替换为>something_else。适合更改 fasta 序列的标题

        while ($filelines=~ />(.*)\s/g){
              unless ($1 =~ /else/i){
                      $filelines =~ s/($1)/$1\_else/;
              }
      
        }
      

      【讨论】:

        【解决方案4】:

        我使用这样的东西:

        s/(?<=prefix)(group)(?=suffix)/$1 =~ s|text|rep|gr/e;
        

        例子:

        在以下文本中,我想规范化空格,但::=之后:

        some    text     := a   b        c d   e   ;
        

        可以通过以下方式实现:

        s/(?<=::=)(.*)/$1 =~ s|\s+| |gr/e
        

        结果:

        some    text     := a b c d e ;
        

        解释:

        (?&lt;=::=):后向断言匹配::=

        (.*)::=之后的所有内容

        $1 =~ s|\s+| |gr:使用捕获的组标准化空白。请注意r 修饰符,它确保不要尝试修改只读的$1。使用不同的子分隔符 (|) 来不终止替换表达式。

        /e:将替换文本视为 perl 表达式。

        【讨论】:

          【解决方案5】:

          使用lookaround assertions。引用文档:

          Lookaround 断言是与特定模式匹配的零宽度模式,但不将其包含在 $&amp; 中。正断言在其子模式匹配时匹配,负断言在其子模式失败时匹配。 Lookbehind 将文本匹配到当前匹配位置,lookahead 匹配当前匹配位置之后的文本。

          如果字符串的开头有固定长度,你可以这样做:

          s/(?<=prefix)(your capture)(?=suffix)/$1/
          

          但是,?&lt;= 不适用于可变长度模式(从 Perl 5.30 开始,它接受长度小于 255 个字符的可变长度模式,这使得| 的使用成为可能,但仍然阻止@ 的使用987654328@)。解决方法是使用\K 而不是(?&lt;=)

          s/.*prefix\K(your capture)(?=suffix)/$1/
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-11-12
            • 2020-09-14
            • 1970-01-01
            • 1970-01-01
            • 2012-03-01
            • 2021-09-06
            • 1970-01-01
            • 2013-06-27
            相关资源
            最近更新 更多