【问题标题】:How to replace consecutive and identical characters in Perl?如何在 Perl 中替换连续且相同的字符?
【发布时间】:2019-09-06 19:33:48
【问题描述】:

我有一个字符串 XXXXYYYYZZZYYZZZYYYY 需要转换为 XXXXAAAYZZZAYZZZAAAY

$s =~ s/Y{2}+/AY/g;

这有 2 个问题,{2}+ 会得到 YYYY 到 AYAY;并且 AY 的长度与YYYY 不同(期望AAAY

如何在 perl 中完成这项工作?

【问题讨论】:

    标签: regex string perl replace


    【解决方案1】:

    使用“前瞻”:

    $s =~ s/Y(?=Y+)/A/g;
    

    (?=Y+) 表示“后跟一个或多个Y 字符”,因此任何Y 字符后跟另一个Y 字符都将替换为A

    More info from perlretut

    【讨论】:

      【解决方案2】:

      总是有不止一种方法可以做到这一点。我的建议是获取除最后一个之外的所有 Y,然后使用它创建一个相同长度的 As 字符串。 e 修饰符告诉 perl 在替换端执行代码而不是直接使用它,r 修饰符告诉 =~ 返回替换结果而不是直接修改输入文本(对这些有用-liner 测试等)。

      $ perl -E 'say shift =~ s/(Y+)(?=Y)/"A"x length$1/gre' XXXXYYYYZZZYYZZZYYYY
      XXXXAAAYZZZAYZZZAAAY
      

      【讨论】:

      • 这不太一样 - 您将 + 移到捕获之外,因此长度始终为 1,并且您的替换将省略结尾 Y(s),这意味着正在匹配更多文本并因此被替换。是的,它可以在没有前瞻的情况下工作,但我更喜欢它。
      • 我的错,是的(Y+)Y,而不是你可以用捕获组的长度替换为A 和一个额外的Y
      • 正则表达式:通常在第一次尝试时不起作用。 :) 这就是为什么我不得不尝试三遍才能让上面的答案起作用:)
      【解决方案3】:

      $s =~ s/Y{2}+/AY/g
      RHS 模式是模棱两可的模式:Y{2}+,这是很少使用的正则表达式模式,除非 {}+ 在少数高级正则表达式引擎中很少使用,可能包括 perl,作为称为“原子分组”的正则表达式功能。
      您可能指的是(Y{2})+ which is (YY)+Y{2,},即YY+
      在 perl 中,它支持lookaround 功能,简单易行

      perl -e '$s=XXXXYYYYZZZYYZZZYYYY ;$s =~ s/Y(?=Y)/A/g;print $s'
      

      实际上,像 sed 这样的低级正则表达式引擎仍然可以做到这一点,尽管方式繁琐、不安

      echo XXXXYYYYZZZYYZZZYYYY |sed -E 's/YY+/&\n/g;s/Y/A/g;s/A\n/Y/g'
      

      【讨论】:

        猜你喜欢
        • 2015-09-01
        • 2021-12-01
        • 1970-01-01
        • 2021-03-13
        • 2020-07-19
        • 1970-01-01
        • 1970-01-01
        • 2021-11-17
        • 1970-01-01
        相关资源
        最近更新 更多