以下代码片段对我不起作用。
fragment = Regex.Replace(fragment, "<!--.*?-->", String.Empty , RegexOptions.Multiline );
RegExOptions.Singleline
,它将正常工作。
当不在Singleline模式下时,点匹配任何字符,除了换行符。Singleline
和Multiline
不是互斥的。它们执行两个独立的操作。引用MSDN的话:
多行模式。更改^和$的含义,使它们分别匹配任何行的开头和结尾,而不仅仅是整个字符串的开头和结尾。
单行模式。更改点(.)的含义,使它匹配每个字符(而不是除\n以外的所有字符)。Simon Mourier said:
This is a sample code to remove comments:
static void Main(string[] args) { HtmlDocument doc = new HtmlDocument(); doc.Load("filewithcomments.htm"); doc.Save(Console.Out); // show before RemoveComments(doc.DocumentNode); doc.Save(Console.Out); // show after } static void RemoveComments(HtmlNode node) { if (!node.HasChildNodes) { return; } for (int i=0; i<node.ChildNodes.Count; i++) { if (node.ChildNodes[i].NodeType == HtmlNodeType.Comment) { node.ChildNodes.RemoveAt(i); --i; } } foreach (HtmlNode subNode in node.ChildNodes) { RemoveComments(subNode); } }
HtmlDocument doc = new HtmlDocument
{
OptionFixNestedTags = true,
OptionOutputAsXml = true
};
doc.LoadHtml(str);
// Script comments from the document.
if (doc.DocumentNode != null)
{
HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("//comment()");
if (nodes != null)
{
foreach (HtmlNode node in from cmt in nodes
where (cmt != null
&& cmt.InnerText != null
&& !cmt.InnerText.ToUpper().StartsWith("DOCTYPE"))
&& cmt.ParentNode != null
select cmt)
{
node.ParentNode.RemoveChild(node);
}
}
}
这段代码能够正确地去除注释,并忽略HtmlAgilityPack中被视为注释的doctype。
虽然正则表达式在受控条件下可以工作,但如果你要处理来自互联网的HTML,我建议使用HtmlAgilityPack。那里的HTML非常不可预测,而且正则表达式会出错。
<!--(\n|.)*?-->
。此外,这个问题可以通过简单地添加 SingleLine 标志来解决,它修改了 . 以接受换行符。 - Matthew Scharley(\n|.)*
,因为它不精确,极其低效,需要大量回溯,并且是多余的,因为仅带有 (?s)
或 RegexOptions.Singleline
的 .
可以更有效地完成工作。由于使用这种不幸的模式已经报告了很多问题,请考虑删除帖子或更改解决方案。 - Wiktor Stribiżew
^
和$
锚点的行为。 - Alan Moore