【问题标题】:Clean everything after start till to the end point从开始到结束后清理所有东西
【发布时间】:2013-07-19 22:37:16
【问题描述】:

想从一个起点到终点清理所有东西

例子:

    <!--
        <group>
                <name>Octopus</name>
                <inventory>
                        <inventoryName>octopus</inventoryName>
                        <decoder>DFFDD</decoder>
                        <command>cat /etc/hosts</command>
                </inventory>
        </group>
 -->

&lt;!-- 是起点,--&gt; 是终点,有时内容是多行到终点。 我想删除这些标签中的所有内容。

我尝试用 sed 开始一些事情,例如:

sed 's/^&lt;\!--//g' 但不知道如何在看到结束标记后继续捕获所有内容并进行清理。

【问题讨论】:

  • 你能保证:每个&lt;!-- some --&gt; 只在一行中吗?或者这里也有多行 cmets。你能确保不是像&lt;!-- some &lt;!-- another --&gt; one --&gt; 这样的嵌套 cmets 吗?
  • 如果要解析 HTML,请使用 HTML 解析器,而不是正则表达式。
  • 是的,有时是多行@jm666
  • @jm666 在有效的 HTML 中不能有这样的嵌套 cmets。

标签: perl bash sed awk


【解决方案1】:

. 匹配换行符的非贪婪替换正则表达式,

$string =~ s|<!-- .*? -->||xsg;

【讨论】:

  • 如何将它用于 sed 或其他东西?!
  • @KalinBorisov,就是 perl 语法
  • @glenn jackman Aham,但如何使用它来更改所有内容,例如在一个文件中。我尝试使用perl "$string =~ s|&lt;!-- .*? --&gt;||xsg;"
  • 可以短至perl -0777 -lpe 's|&lt;!-- .*? --&gt;||xsg' file.xml,一次性修改整个文件。使用-i 开关将更改保存回文件中。
【解决方案2】:

如果我得到你想要做的,你想删除 cmets。对吧?

这样的事情呢?

<!--
     blah blah blah -->

或者

<!-- blah blah blah -->

或者

<!-- blah blah blah
-->

甚至这个?

 <foo><bar> <!-- <fubar>blah blah</fubar> --> </bar></foo>

您不能在 XML 上使用正则表达式,因为 XML 太复杂了。解析 XML 数据的 Perl 库有很多,您应该使用它们。

虽然它不再是首选,但XML::Simple 可以完全按照您的意愿行事,而且绝对不会大惊小怪。 XML::Simple 可以将您的 XML 文件重建为兼容版本。实体可能不完全匹配,但它将与您的旧结构兼容。而且,XML::Simple 删除了 cmets。

use strict;
use warnings;
use XML::Simple;

my $xml_struct_ref = XMLin( $xml_file );
my $xml_file_output = XMLout ( $xml_struct_ref );

然后,您只需将$xml_file_output 写入新的XML 文件。已删除所有 cmets!

【讨论】:

  • 恕我直言,这是 ****only**** 正确的解决方案 - 至少从当前答案来看。 ;)
【解决方案3】:

GNU 的代码:

sed -r '/<!--/,/-->/{//!d;s/(.*<!--).*/\1/;s/.*(-->.*)/\1/}' file

会话协议:

    $ cat file
    test line #1
    <AXXX> <!--  <BXXX>
        <group>
            <name>Octopus</name>
            <inventory>
                <inventoryName>octopus</inventoryName>
                <decoder>DFFDD</decoder>
                <command>cat /etc/hosts</command>
            </inventory>
        </group>
    <CXXX> --> <DXXX>
    test line 12
$ sed -r '/<!--/,/-->/{//!d;s/(.*<!--).*/\1/;s/.*(-->.*)/\1/}' file
test line #1
<AXXX> <!--
--> <DXXX>
test line 12

【讨论】:

    【解决方案4】:

    Perl 解决方案:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    my $filename = $ARGV[0];
    
    open FILE, "<$filename" or die $!;
    local $/;
    my $text = <FILE>;
    close FILE;
    
    $text =~ s/<!--[\s\S]*?-->//g;
    
    open FILE, ">$filename" or die $!;
    print FILE $text;
    close FILE;
    

    您需要[\s\S]*?(或者(.|\n))来实现任何字符的最短匹配,包括换行符。 . 单独对多行字符串不起作用,因为它匹配除换行符以外的任何字符。

    像这样运行脚本:

    ./script.pl /path/to/your.file
    

    【讨论】:

      【解决方案5】:

      HTML::Parser可以找到类似的sn-p:

      perl -0777 -MHTML::Parser -nE 'HTML::Parser->new(default_h=>[sub{print shift},"text"],comment_h=>[""])->parse($_)||die $!' < file.html >decommented.html
      

      在下一个 html 上测试:

      simple
      <!-- this is an comment -->
      multi
      <!--
      this is an
      multiline comment
      -->
      stupid
      <img src="copen.jpg" alt='image of open tag <!--'>
      <img src="cclose.jpg" alt='image of closing tag -->'>
      js
      <script>
      alert("<!-- here -->");
      </script>
      end
      

      并打印:

      simple
      
      multi
      
      stupid
      <img src="copen.jpg" alt='image of open tag <!--'> <img src="cclose.jpg" alt='image of closing tag -->'>
      js
      <script>
      alert("<!-- here -->");
      </script>
      

      【讨论】:

      • AHHHHH.... 在输入答案之前我没有重新加载页面。我假设你有HTML - 你稍后添加了xml 示例。我不太确定如何为 XML 工作 - 应该,但我不是 100% 确定。抱歉混淆。但是,有一件事:你应该使用解析器。正确使用正则表达式是不可能的。请参阅我的示例 html。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 2021-08-05
      • 2012-02-11
      • 1970-01-01
      • 2019-06-10
      相关资源
      最近更新 更多