使用正则表达式删除HTML注释标签

10
This is how my text (html) file looks like
    <!--
     |                                |
     |  This is a dummy comment       |
     |      please delete me          |
     |         asap                   |
     |                                |
      ________________________________
     | -->

    this is another line 
    in this long dummy html file...
    please do not delete me

我正在尝试使用sed删除评论:

cat file.html | sed 's/.*<!--\(.*\)-->.*//g'

它不起作用 :( 我做错了什么?

非常感谢您的帮助!


1
也许是:/<!--[.\s\S]*?-->/ - drudge
1
@jnpcl:看起来像是Perl。在sed中行不通。 - Dennis Williamson
2
适用于通常的警告 - Dennis Williamson
@Dennis:这是我在使用RegExPal时有效的方法,我没有意识到sed使用不同的正则表达式语法。 - drudge
4个回答

17

patrickmdnet的答案是正确的。以下是使用扩展正则表达式在一行中的答案:

cat file.html | sed -e :a -re 's/<!--.*?-->//g;/<!--/N;//ba'

这里有一个很好的资源,可以帮助你更多地了解sed。这个sed是一行代码#92的改编版本。

http://www.catonmat.net/blog/sed-one-liners-explained-part-three/


谢谢Brian!你太棒了 :) 你的sed命令中的:a是什么意思? - Zenet
它创建了一个名为'a'的分支标签。末尾的“//ba”是在跳转到'a'。 - Brian Clements
在GNU sed中,ba前面的//是否必要?我不需要它。 - Dennis Williamson
双斜杠是前一个表达式(即/<!--/)的简写。它决定了分支是否会被执行(如果需要,返回并获取更多行到缓冲区中)。我猜想如果没有它,分支总是会被执行,整个文件将被读入一个缓冲区中。对于非常大的文件可能会有问题,但我不确定。 - Brian Clements

9
你原来的尝试存在一个问题,就是正则表达式只能处理完全在一行上的注释。此外,前导和尾随的“.*”将删除非注释文本。
最好使用现有的代码而不是自己编写。

http://sed.sourceforge.net/grabbag/scripts/strip_html_comments.sed

#! /bin/sed -f
# Delete HTML comments
# i.e. everything between <!-- and -->
# by Stewart Ravenhall <stewart.ravenhall@ukonline.co.uk>

/<!--/!b
:a
/-->/!{
    N
    ba
}
s/<!--.*-->//

(来自http://sed.sourceforge.net/grabbag/scripts/

请参考此链接,了解使用Perl模块删除HTML注释的各种方法(使用Regexp::Common、HTML::Parser或File::Comments)。我相信还有使用其他工具的方法。

http://www.perlmonks.org/?node_id=500603


3

如果你想的话,我认为你可以使用 awk 来完成这个任务。开始:

[~] $ more test.txt
<!--

An HTML style comment 

-->

Some other text

<div>
<p>blah</p>
</div>

<!-- Whoops
     Another comment -->
<span>Something</span>

awk的结果:

[~]$ cat test.txt | awk '/<!--/ {off=1} /-->/ {off=2} /([\s\S]*)/ {if (off==0) print; if (off==2) off=0}'
Some other text

<div>
<p>blah</p>
</div>

<span>Something</span>

我通过对awk代码进行轻微更改来解决@john-jones的问题,在这里 - Barumpus

0

希望能够改进eldarerathis提供的基于awk的答案--

下面的代码解决了john-jones提出的问题。

在这个版本中,保留了html注释开始前的前缀以及html注释结束后的后缀。

$ cat some-file | awk '/<!--/ { mode=1; start=index($0,"<!--"); prefix=substr($0,1,start-1); } /-->/ { mode=2; start=index($0, "-->")+3; suffix=substr($0,start); print prefix suffix; prefix=""; suffix=""; } /./ { if (mode==0) print $0; if (mode==2) mode=0; }'

例如

$ cat test.txt
<!--

An HTML style comment

-->

<meta charset="utf-8"> <!-- charset encoding must be within the first 1024 bytes of the document -->
Some other text

<div>
<p>blah</p>
</div>

<!-- Whoops
     Another comment -->
<span>Something</span>

<div> <!-- start of foo -->
foo
</div> <!-- end of foo -->

<div> <!-- start of multiline comment
bar
end of multiline comment --> </div>

$ cat test.txt | awk '/<!--/ { mode=1; start=index($0,"<!--"); prefix=substr($0,1,start-1); } /-->/ { mode=2; start=index($0, "-->")+3; suffix=substr($0,start); print prefix suffix; prefix=""; suffix=""; } /./ { if (mode==0) print $0; if (mode==2) mode=0; }'

Some other text
<div>
<p>blah</p>
</div>

<span>Something</span>
<meta charset="utf-8">
<div>
foo
</div>
<div>  </div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接