在 Javascript 中使用 Regex 删除 HTML 注释

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5653207/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:17:31  来源:igfitidea点击:

Remove HTML comments with Regex, in Javascript

javascriptregex

提问by rodbv

I've got some ugly HTML generated from Word, from which I want to strip all HTML comments.

我有一些从 Word 生成的难看的 HTML,我想从中删除所有 HTML 注释。

The HTML looks like this:

HTML 如下所示:

<!--[if gte mso 9]><xml> <o:OfficeDocumentSettings> <o:RelyOnVML/> <o:AllowPNG/> </o:OfficeDocumentSettings> </xml><![endif]--><!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:TrackMoves/> <w:TrackFormatting/> <w:HyphenationZone>21</w:HyphenationZone> <w:PunctuationKerning/> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:DoNotPromoteQF/> <w:LidThemeOther>NO-BOK</w:LidThemeOther> <w:LidThemeAsian>X-NONE</w:LidThemeAsian> <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript> <w:Compatibility> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:SplitPgBreakAndParaMark/> <w:EnableOpenTypeKerning/> <w:DontFlipMirrorIndents/> <w:OverrideTableStyleHps/> </w:Compatibility> <m:mathPr> <m:mathFont m:val="Cambria Math"/> <m:brkBin m:val="before"/> <m:brkBinSub m:val="&#45;-"/> <m:smallFrac m:val="off"/> <m:dispDef/> <m:lMargin m:val="0"/> <m:rMargin m:val="0"/> <m:defJc m:val="centerGroup"/> <m:wrapIndent m:val="1440"/> <m:intLim m:val="subSup"/> <m:naryLim m:val="undOvr"/> </m:mathPr></w:WordDocument> </xml><![endif]-->

..and the regex I am using is this one

..我使用的正则表达式就是这个

html = html.replace(/<!--(.*?)-->/gm, "")

But there seems to be no match, the string is unchanged.

但是好像没有匹配,字符串没有变化。

What I am missing?

我缺少什么?

回答by Mike Samuel

The regex /<!--[\s\S]*?-->/gshould work.

正则表达式/<!--[\s\S]*?-->/g应该可以工作。

You're going to kill escaping text spansin CDATA blocks.

您将杀死CDATA 块中的转义文本跨度

E.g.

例如

<script><!-- notACommentHere() --></script>

and literal text in formatted code blocks

和格式化代码块中的文字文本

<xmp>I'm demoing HTML <!-- comments --></xmp>

<textarea><!-- Not a comment either --></textarea>

EDIT:

编辑:

This also won't prevent new comments from being introduced as in

这也不会阻止引入新的评论,如

<!-<!-- A comment -->- not comment text -->

which after one round of that regexp would become

在一轮正则表达式之后将成为

<!-- not comment text -->

If this is a problem, you can escape <that are not part of a comment or tag (complicated to get right) or you can loop and replace as above until the string settles down.

如果这是一个问题,您可以转义<不属于注释或标签的部分(复杂到正确),或者您可以按上述方式循环和替换,直到字符串稳定下来。



Here's a regex that will match comments including psuedo-commentsand unclosed comments per the HTML-5 spec. The CDATA section are only strictly allowed in foreign XML. This suffers the same caveats as above.

这是一个正则表达式,它将根据 HTML-5 规范匹配注释,包括伪注释和未关闭的注释。CDATA 部分只在外部 XML 中被严格允许。这受到与上述相同的警告。

var COMMENT_PSEUDO_COMMENT_OR_LT_BANG = new RegExp(
    '<!--[\s\S]*?(?:-->)?'
    + '<!---+>?'  // A comment with no body
    + '|<!(?![dD][oO][cC][tT][yY][pP][eE]|\[CDATA\[)[^>]*>?'
    + '|<[?][^>]*>?',  // A pseudo-comment
    'g');

回答by rodbv

You should use the /smodifier

你应该使用/s修饰符

html = html.replace(/<!--.*?-->/sg, "")

html = html.replace( /<!--.*?-->/sg, "")

Tested in perl:

在 perl 中测试:

use strict;
use warnings;

my $str = 'hello <!--[if gte mso 9]><xml> <o:OfficeDocumentSettings> <o:RelyOnVML/> <o:AllowPNG/> </o:OfficeDocumentSettings> </xml><![endif]--><!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:TrackMoves/> <w:TrackFormatting/> <w:HyphenationZone>21</w:HyphenationZone> <w:PunctuationKerning/> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:DoNotPromoteQF/> <w:LidThemeOther>NO-BOK</w:LidThemeOther> <w:LidThemeAsian>X-NONE</w:LidThemeAsian> <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript> <w:Compatibility> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:SplitPgBreakAndParaMark/> <w:EnableOpenTypeKerning/> <w:DontFlipMirrorIndents/> <w:OverrideTableStyleHps/> </w:Compatibility> <m:mathPr> <m:mathFont m:val="Cambria Math"/> <m:brkBin m:val="before"/> <m:brkBinSub m:val="&#45;-"/> <m:smallFrac m:val="off"/> <m:dispDef/> <m:lMargin m:val="0"/> <m:rMargin m:val="0"/> <m:defJc m:val="centerGroup"/> <m:wrapIndent m:val="1440"/> <m:intLim m:val="subSup"/> <m:naryLim m:val="undOvr"/> </m:mathPr></w:WordDocument> </xml><![endif]-->world!';

$str =~ s/<!--.*?-->//sg;
print $str;

Output:
hello world!

输出:
hello world!

回答by Aurielle Perlmann

this works also for multiline - (<!--.*?-->)|(<!--[\w\W\n\s]+?-->)

这也适用于多行 - (<!--.*?-->)|(<!--[\w\W\n\s]+?-->)

enter image description here

在此处输入图片说明

回答by Sachin Gaur

const regex = /<!--(.*?)-->/gm;
const str = `You will be able to see this text. <!-- You will not be able to see this text. --> You can even comment out things in <!-- the middle of --> a sentence. <!-- Or you can comment out a large number of lines. --> <div class="example-class"> <!-- Another --> thing you can do is put comments after closing tags, to help you find where a particular element ends. <br> (This can be helpful if you have a lot of nested elements.) </div> <!-- /.example-class -->`;
const subst = ``;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);

回答by Zach Bloomquist

This is based off Aurielle Perlmann's answer, it supports all cases (single-line, multi-line, un-terminated, and nested comments):

这是基于Aurielle Perlmann 的回答,它支持所有情况(单行、多行、未终止和嵌套注释):

/(<!--.*?-->)|(<!--[\S\s]+?-->)|(<!--[\S\s]*?$)/g

https://regex101.com/r/az8Lu6/1

https://regex101.com/r/az8Lu6/1

regex101 output

regex101 输出

回答by Dmitry Negoda

html = html.replace("(?s)<!--\[if(.*?)\[endif\] *-->", "")