【问题标题】:C# How to delete XML/HTML comments with regular expressionC# 如何使用正则表达式删除 XML/HTML 注释
【发布时间】:2009-08-20 05:04:34
【问题描述】:

下面的片段对我不起作用。

fragment = Regex.Replace(fragment, "<!--.*?-->", String.Empty , RegexOptions.Multiline  );

【问题讨论】:

    标签: c# regex


    【解决方案1】:

    改为RegExOptions.Singleline 就可以了。 当不在单行模式下时,点匹配任何字符,除了换行符。

    请注意,SinglelineMultiline 并不相互排斥。他们做两件不同的事情。引用 MSDN:

    多行模式。改变的意思 ^ 和 $ 所以它们在开头匹配 和结束,分别,任何行, 而不仅仅是开始和结束 整个字符串。

    单行模式。变化 点 (.) 的含义,所以它 匹配每个字符(而不是 除了 \n) 之外的所有字符。

    其他人已经建议使用 HTML Agility Pack。我只是觉得你应该解释一下为什么你的正则表达式不起作用:)

    【讨论】:

    • 是的,它有效。起初我没有提供第三个参数,它没有工作,我认为 RegExOptions.SingleLine 是隐含的,但看起来 Multiline 是默认的。
    • 单行和多行并不是对立的,无论名称似乎暗示什么。这两个选项默认都是关闭的,设置一个对另一个没有影响。 Singleline 改变点元字符的行为,Multiline 改变 ^$ 锚点的行为。
    • @Alan M:确实,我的回答在这方面措辞不佳。我已经更新了一点。
    【解决方案2】:

    请不要使用正则表达式来处理标记语言 - 您需要使用专为此类工作构建的更好的工具。

    请改用Html Agiliy Pack。我什至在this article 中找到了一个阅读器(名为 Simon Mourier)的 cmets,该函数使用 Html Agility Pack 从文档中删除 cmets:

    Simon Mourier说:

    这是要删除的示例代码 厘米:

    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);
        }
    }
    

    【讨论】:

    • 我在其他线程中看到了您的类似评论。我不相信为什么我应该使用更好的工具来偶尔使用更好的工具来提取 html 页面上开始和结束标记之间的hrefs,其中一些人评论了。
    • 安德鲁是对的。您不能使用正则表达式解析 [X][HT]ML,除非 (a) 您事先知道正在使用一组非常有限且固定的内容,或者 (b) 您不介意结果中有很多错误。解析 cmets 比解析链接更不容易出错,因为链接格式的可变性要大得多,但它仍然不可靠。
    • 代码示例不起作用。枚举集合时不能修改节点
    【解决方案3】:

    这是通过 C# 剥离 cmets 的最高 Google 结果,这是我的 HtmlAgilityPack 代码。

            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);
                    }
                }
            }
    

    这在剥离 cmets 时可以正常工作,并忽略 HtmlAgilityPack 将其视为注释的 doctype。

    虽然正则表达式确实在受控条件下工作。如果您正在处理来自狂野网络的 HTML,那么我建议您使用 HtmlAgilityPack。那里的 HTML 非常不可预测,正则表达式会中断。

    【讨论】:

      【解决方案4】:

      这个对我有用:

      <!--(\n|.)*-->
      

      但我认为您可以将普通的 XML 文档用于 XML,或者将 HtmlAgilityPack 用于 HTML。强烈建议使用 RegEx 解析标记。

      【讨论】:

      • 您应该在乘数上放置一个非贪婪量词,即。 &lt;!--(\n|.)*?--&gt; 另外,这个问题可以通过简单地添加修改 .也接受换行符..
      • @Matthew。是的。我同意。你理论上是对的。但是我尝试了 SingleLine 标志,它并没有改变结果。非贪婪和贪婪的工作也是如此。使用 radsoftware.com.au/?from=RegexDesigner 测试
      • 你永远不应该使用(\n|.)*,因为它不精确,由于涉及大量回溯,效率极低,并且是多余的,因为仅仅.(?s)RegexOptions.Singleline就可以完成这项工作以更有效的内置方式。由于使用了这种不幸的模式,已经报告了很多问题。请考虑删除帖子,或更改解决方案。
      猜你喜欢
      • 2011-05-02
      • 2011-08-04
      • 1970-01-01
      • 2010-11-08
      • 1970-01-01
      • 2011-04-01
      • 1970-01-01
      • 2015-02-25
      • 2011-01-28
      相关资源
      最近更新 更多