Удалите HTML-комментарии с помощью Regex, в Javascript
У меня есть уродливый HTML, созданный из Word, из которого я хочу удалить все комментарии HTML.
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="--"/> <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]-->
.. и регулярное выражение, которое я использую, - это
html = html.replace(/<!--(.*?)-->/gm, "")
Но похоже, что нет совпадения, строка не изменяется.
Что мне не хватает?
Ответы
Ответ 1
Регулярное выражение /<!--[\s\S]*?-->/g
должно работать.
Вы собираетесь убить экранирование пробелов в блоках CDATA.
например.
<script><!-- notACommentHere() --></script>
и буквальный текст в форматированных блоках кода
<xmp>I'm demoing HTML <!-- comments --></xmp>
<textarea><!-- Not a comment either --></textarea>
EDIT:
Это также не помешает появлению новых комментариев, как в
<!-<!-- A comment -->- not comment text -->
который после одного раунда этого регулярного выражения станет
<!-- not comment text -->
Если это проблема, вы можете выйти из <
, которые не являются частью комментария или тега (сложно получить право), или вы можете выполнить цикл и заменить, как указано выше, до тех пор, пока строка не установится.
Здесь существует регулярное выражение, которое будет соответствовать комментариям, включая psuedo-comments и незакрытые комментарии по спецификации 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');
Ответ 2
Вы должны использовать модификатор /s
html = html.replace(/<!--.*?-->/sg
, "")
Протестировано в 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="--"/> <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;
Вывод:
hello world!
Ответ 3
это работает также для многострочных - (<!--.*?-->)|(<!--[\w\W\n\s]+?-->)
![enter image description here]()
Ответ 4
html = html.replace("(?s)<!--\\[if(.*?)\\[endif\\] *-->", "")
Ответ 5
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);
Ответ 6
Это основано на ответе Ауриэль Перлманн, оно поддерживает все случаи (однострочные, многострочные, неразрывные и вложенные комментарии):
/(<!--.*?-->)|(<!--[\S\s]+?-->)|(<!--[\S\s]*?$)/g
https://regex101.com/r/az8Lu6/1
![regex101 output]()