【问题标题】:Replace html tag with attributes by other tag in C#用C#中的其他标签将html标签替换为属性
【发布时间】:2013-01-23 23:18:20
【问题描述】:

基本上,我想用其他标签替换html标签,例如:

</br> --> <LineBreak/>
<p> --> <Paragraph>

一开始,我用了

convertedHtml = html.replace("</br>","<LineBreak/>");

这种方法的问题是它需要管理所有案例,我想要一个通用类。例如,此标签内容无法使用此方法:

<p class="foo"> --> <Paragraph>
<p id="bar"> --> <Paragraph>
.....

我该如何解决这个问题?

edit:请注意,我事先不知道标签中有哪些属性。我想替换包含“p”、“/p”、“br”、“b”、...的标签

【问题讨论】:

    标签: c# replace tags html


    【解决方案1】:

    您可以尝试一些简单的字符串操作,不包括额外的命名空间和工具:

    看看这个例子,也许它可以解决你的问题:

    string html = string.Concat("<p class=\"foo\">", 
                                 "<p class=\"bar\">",
                                 "<p>",
                                 "</br>",
                                 "<P>",
                                 "</BR>"); // tags can be upper case as well
    
    string strAux = html;
    int tagOpenedAt=-1, tagClosedAt=-1;
    bool isError = false;
    
    do
    {
       tagOpenedAt = strAux.IndexOf('<');
       tagClosedAt = strAux.IndexOf('>');
       if(tagOpenedAt<tagClosedAt)
       {
           string fullTag = strAux.Substring(tagOpenedAt, tagClosedAt - tagOpenedAt + 1);
    
           //<p> --> <Paragraph>
           if (fullTag.ToLower().Equals("<p>") || fullTag.ToLower().StartsWith("<p ")) 
               html = html.Replace(fullTag, "<Paragraph>");
    
           //</br> --> <LineBreak/>
           if (fullTag.ToLower().Equals("</br>")) 
               html = html.Replace(fullTag, "<LineBreak/>");
    
           //more if conditions as you need them
    
           strAux = strAux.Substring(tagClosedAt + 1);
       }
       else
       {
           isError = true;
       }
    } 
    while (tagOpenedAt>-1 && tagClosedAt>-1 && !isError);
    

    对不起,糟糕的代码,也许你可以通过简单地执行一次 .ToLower() 来改进,而不是在每个 if 语句中。另外,我没有检查坏标签,代码只是假设 html 是有效的。

    刚刚编辑了一点

           string html = string.Concat("<p class=\"foo\">","\n",
                                        "<p class=\"bar\">", "\n",
                                        "<p>", "\n",
                                        "</br>", "\n",
                                        "<P>", "\n",
                                        "</BR>");
    
            Console.WriteLine("HTML is :\n{0}\n", html);
    
            string strAux = html;
            int tagOpenedAt=-1, tagClosedAt=-1;
            bool isError = false;
    
            do
            {
                tagOpenedAt = strAux.IndexOf('<');
                tagClosedAt = strAux.IndexOf('>');
                if(tagOpenedAt < tagClosedAt)
                {
                    string _fullTag = strAux.Substring(tagOpenedAt, tagClosedAt - tagOpenedAt + 1);
                    string _lower = _fullTag.ToLower();
                    string _replace = null;
    
                    //<p> --> <Paragraph>
                    if (_lower.Equals("<p>") || _lower.StartsWith("<p "))
                        _replace = "<Paragraph>";
    
                    //</br> --> <LineBreak/>
                    if (_lower.Equals("</br>")) 
                        _replace = "<LineBreak/>";
    
                    //more if conditions as you need them
    
                    if(_replace != null)
                    {
                        html = html.Replace(_fullTag, _replace);
                        Console.WriteLine("Replaced {0} with {1}", _fullTag, _replace);
                    }
    
                    strAux = strAux.Substring(tagClosedAt + 1);
                }
                else
                {
                    isError = true;
                }
            } 
            while (tagOpenedAt>-1 && tagClosedAt>-1 && !isError);
    
        Console.WriteLine("\nNew html is :\n{0}",html);
    

    【讨论】:

      【解决方案2】:

      我查看了我的一个旧项目,在那里我做了类似的事情。

      看看我一直在使用的这个方法:

          private static Regex _validAttributeOrTagNameRegEx = 
                             new Regex(@"^\w+$", RegexOptions.Compiled |RegexOptions.IgnoreCase);
              private const string STR_RemoveHtmlAttributeRegex = 
                                 @"(?<=<)([^/>]+)(\s{0}=['""][^'""]+?['""])([^/>]*)(?=/?>|\s)";
          public static string RemoveHtmlAttribute(this string input, string attributeName) {
             if (_validAttributeOrTagNameRegEx.IsMatch(attributeName)) {
                Regex reg = new Regex(string.Format(STR_RemoveHtmlAttributeRegex, attributeName),
                   RegexOptions.IgnoreCase);
                return reg.Replace(input, item => item.Groups[1].Value + item.Groups[3].Value);
             } else {
                throw new ArgumentException("Not a valid HTML attribute name", "attributeName");
             }
          }
      

      我不确定这是否符合您的要求,但它可能是关于如何解决它的一个想法。从 html-tags 中删除属性后,您可以使用旧方法 convertedHtml = html.replace("&lt;/br&gt;","&lt;LineBreak/&gt;");

      【讨论】:

        【解决方案3】:

        也许你可以使用 HTML Agility Pack (http://htmlagilitypack.codeplex.com/)

        您可以通过 NuGet 获取它,它允许您使用 xPath 从 htmlDoc 获取节点列表...然后您可以遍历这些列表并对每个节点执行操作...

        【讨论】:

        • +1 类似的问题在这个网站上已经被问过很多次了,这是首选的方法。
        【解决方案4】:

        您应该使用正则表达式来解决这个问题。更多信息请访问this site。它将为您提供区分大小写/不区分大小写匹配的选项。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-12
          • 1970-01-01
          • 2013-05-01
          • 2017-01-24
          • 2021-07-30
          相关资源
          最近更新 更多