【问题标题】:REGEX pattern to increment a counter on replacements正则表达式模式来增加替换计数器
【发布时间】:2012-04-06 04:18:37
【问题描述】:

在替换模式中,有没有办法像在计数器中一样打印替换的 NUMBER?

我需要在 HTML 文件中处理一系列代码块,但在每个替换的块中,我需要将计数器加 1。

所以

<p class-"foo">Some text</p>
<p class-"foo">Other text</p> 

需要

<p id="1">Some text</p>
<p id="2">Other text</p> 

我有很多行,我希望避免手动输入这些数字。我该怎么做,最简单的方法?

【问题讨论】:

    标签: ruby regex perl sed


    【解决方案1】:

    在 Perl 中:

    my $html = <<END;
    <p class="foo">Some text</p>
    <p class="foo">Other text</p> 
    END
    
    my $n = 0;
    $html =~ s/<p class="toc0">/'<p class="foo" id="'.++$n.'">'/eg;
    
    print $html;
    

    输出

    <p id="1">Some text</p>
    <p id="2">Other text</p> 
    

    用于从文件中读取的命令行版本

    perl -pe 's/<p class="toc0">/q(<p class="foo" id=").++$n.q(">)/eg' myfile.html
    

    【讨论】:

    • 这看起来可以做我想做的事,但为了更容易理解,我过度简化了我的代码。我实际上希望用几个反向引用替换:&lt;p class="toc0"&gt;&lt;a href="part0004.xhtml#c01"&gt;TOOLS AND MATERIALS&lt;/a&gt;&lt;/p&gt; 我需要捕获和重新使用 href 和链接文本的地方。我试过了,但一定遗漏了一些东西:$html =~ s/&lt;p class="toc0"&gt;&lt;a href="(.*?)"&gt;(.*?)&lt;/a&gt;/'&lt;p class="foo" id="'.++$n.'"&gt;&lt;a href="'.$1.'"&gt;'.$2.'&lt;/a&gt;/eg;
    • 我找到了,标点符号放错了。谢谢。如何修改此脚本以将文本文件作为输入,而不是像上面那样将文本放入其中?
    • @Steve:我在答案中添加了命令行版本。根据您的说法,我认为没有理由捕获并放回您想要保留的部分 - 只需编辑开头的&lt;p class="toc0"&gt;,其余部分保持不变。
    【解决方案2】:
    irb(main):001:0> s = %Q{<p class-"foo">Some text</p>\n<p class-"foo">Other text</p>}
    irb(main):002:0> id=0; s.gsub(/class-"foo"/) { id+=1; %Q[id="#{id}"] }
    => "<p id=\"1\">Some text</p>\n<p id=\"2\">Other text</p>"
    

    【讨论】:

      【解决方案3】:

      你可以写:

      perl -pe 's/<p class-"foo">/"<p id=\"" . (++$count) . "\">"/eg'
      

      使用/e 标志将替换视为表达式而不是字符串。

      【讨论】:

      • 您的 BEGIN 块是多余的。 ++ 运算符会将未定义的变量递增到 1。
      【解决方案4】:
      perl -pwe 's/<p\s+\Kclass-"foo">/ $i++; qq(id="$i">) /e' yourfile
      

      \K 用于保留前面的内容,在这种情况下很方便。使用经过评估并包含几个(两个)语句的替换也很方便,以避免连接和复杂的引用。只插入整个语句的返回值,即最后一条语句。

      当您尝试过并想要更改文件时,您只需添加-i 选项即可。我建议使用备份,如下所示:

      perl -i.bak -pwe '....etc'
      

      (备份在filename.ext.bak

      【讨论】:

        【解决方案5】:

        使用 awk

        { cat -<<EOS
          <p class-"foo">Some text</p>
          <p class-"foo">Other text</p> 
        EOS
        } | awk '/<p class/{sub(/class-".*"/, "id=\""++i "\"");print}'
        

        输出

        <p id-1>Some text</p>
        <p id-2>Other text</p>
        

        我希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 2011-03-12
          • 1970-01-01
          • 2016-10-20
          • 1970-01-01
          • 1970-01-01
          • 2023-04-07
          • 1970-01-01
          • 2012-02-12
          • 1970-01-01
          相关资源
          最近更新 更多