正则表达式删除HTML标记

时间:2010-09-24 20:21:08

标签: c# .net regex

我正在使用以下Regular Expresion从字符串中删除html标记。它的工作原理除了我留下结束标签。如果我尝试删除<a href="blah">blah</a>,则会离开<a/>

我根本不知道正则表达式语法,并且通过这种方式摸索。拥有RegEx知识的人可以为我提供一个可行的模式。

这是我的代码:

  string sPattern = @"<\/?!?(img|a)[^>]*>";
  Regex rgx = new Regex(sPattern);
  Match m = rgx.Match(sSummary);
  string sResult = "";
  if (m.Success)
   sResult = rgx.Replace(sSummary, "", 1);

我希望删除<a><img>代码的第一次出现。

14 个答案:

答案 0 :(得分:19)

使用正则表达式解析HTML充满了陷阱。 HTML不是常规语言,因此无法使用正则表达式100%正确解析。这只是您将遇到的许多问题之一。最好的方法是使用HTML / XML解析器为您执行此操作。

以下是我写回一篇博文的链接,其中详细介绍了此问题。

话虽如此,这是一个解决这个特殊问题的解决方案。它绝不是一个完美的解决方案。

var pattern = @"<(img|a)[^>]*>(?<content>[^<]*)<";
var regex = new Regex(pattern);
var m = regex.Match(sSummary);
if ( m.Success ) { 
  sResult = m.Groups["content"].Value;

答案 1 :(得分:15)

转过来:

'<td>mamma</td><td><strong>papa</strong></td>'

进入这个:

'mamma papa'

您需要用空格替换标记:

.replace(/<[^>]*>/g, ' ')

并将任何重复的空格减少为单个空格:

.replace(/\s{2,}/g, ' ')

然后用:

修剪前导和尾随空格
.trim();

意味着您的删除标记功能如下所示:

function removeTags(string){
  return string.replace(/<[^>]*>/g, ' ')
               .replace(/\s{2,}/g, ' ')
               .trim();
}

答案 2 :(得分:3)

为了删除标签之间的空格,您可以使用以下方法在输入html的开头和结尾处使用正则表达式和空格的修剪组合:

    public static string StripHtml(string inputHTML)
    {
        const string HTML_MARKUP_REGEX_PATTERN = @"<[^>]+>\s+(?=<)|<[^>]+>";
        inputHTML = WebUtility.HtmlDecode(inputHTML).Trim();

        string noHTML = Regex.Replace(inputHTML, HTML_MARKUP_REGEX_PATTERN, string.Empty);

        return noHTML;
    }

所以对于以下输入:

      <p>     <strong>  <em><span style="text-decoration:underline;background-color:#cc6600;"></span><span style="text-decoration:underline;background-color:#cc6600;color:#663333;"><del>   test text  </del></span></em></strong></p><p><strong><span style="background-color:#999900;"> test 1 </span></strong></p><p><strong><em><span style="background-color:#333366;"> test 2 </span></em></strong></p><p><strong><em><span style="text-decoration:underline;background-color:#006600;"> test 3 </span></em></strong></p>      

输出将只是html标签之间没有空格的文本或html之前或之后的空格: “测试文本测试1测试2测试3”。

请注意,test text之前的空格来自<del> test text </del> html,而test 3之后的空格来自<em><span style="text-decoration:underline;background-color:#006600;"> test 3 </span></em></strong></p> html。

答案 3 :(得分:2)

所以每个人都在谈论的HTML解析器是Html Agility Pack

如果它是干净的XHTML,您还可以使用System.Xml.Linq.XDocumentSystem.Xml.XmlDocument

答案 4 :(得分:2)

如果你只是想删除标签(而不是弄清楚结束标签在哪里),我真的不知道为什么人们对此如此担忧。

这个正则表达式似乎可以处理任何我可以扔给它的东西:

<([\w\-/]+)( +[\w\-]+(=(('[^']*')|("[^"]*")))?)* *>

分解:

  • <([\w\-/]+) - 匹配开始或结束标记的开头。如果你想处理无效的东西,你可以在这里添加更多
  • ( +[\w\-]+(=(('[^']*')|("[^"]*")))?)* - 该位匹配属性 [0, N] 次(* 然后结束)
    • +[\w\-]+ - 是空格后跟属性名称
    • (=(('[^']*')|("[^"]*")))? - 并非所有属性都有赋值 (?)
      • ('[^']*')|("[^"]*") - 在有赋值的属性中,值是带有单引号或双引号的字符串。不允许跳过结束语来使事情顺利进行
  • *> - 整个内容以任意数量的空格结尾,然后是右括号

显然,如果有人向其抛出超级无效的 html,这会搞砸,但它适用于我想出的任何有效内容。在这里测试一下:

const regex = /<([\w\-/]+)( +[\w\-]+(=(('[^']*')|("[^"]*")))?)* *>/g;

const byId = (id) => document.getElementById(id);

function replace() {
console.log(byId("In").value)
  byId("Out").innerText = byId("In").value.replace(regex, "CUT");
}
Write your html here: <br>
<textarea id="In" rows="8" cols="50"></textarea><br>
<button onclick="replace()">Replace all tags with "CUT"</button><br>
<br>
Output:
<div id="Out"></div>

答案 5 :(得分:1)

您可以使用现有的库来剥离html标记。一个好的是Chilkat C# Library

答案 6 :(得分:1)

可以使用:

Regex.Replace(source, "<[^>]*>", string.Empty);

答案 7 :(得分:1)

如果只需要查找开始标记,则可以使用以下正则表达式,它将把标记类型捕获为$ 1(a或img),并将内容(包括结束标记(如果有的话))捕获为$ 2:

(?:<(a|img)(?:\s[^>]*)?>)((?:(?!<\1)[\s\S])*)


如果还需要关闭标签,则应使用以下正则表达式,它将把标签类型捕获为$ 1(a或img),并将内容捕获为$ 2:

(?:<(a|img)(?:\s[^>]*)?>)\s*((?:(?!<\1)[\s\S])*)\s*(?:<\/\1>)

基本上,您只需要在上述正则表达式之一上使用replace函数,并返回$ 2即可获得所需的内容。

有关查询的简短说明:

  • ( )-用于捕获括号内与正则表达式匹配的任何内容。捕获顺序为:$ 1,$ 2等。
  • ?:-在括号“(”之后使用,用于不捕获括号内的内容。
  • \1-正在复制捕获编号1,它是标签类型。我必须捕获标签类型,因此结束标签将与开始标签一致,而不是<img src=""> </a>
  • \s-是空格,因此在打开标签<img后,如果有属性,至少要有1个空格(例如,它与<imgs>不匹配) 。
  • [^>]*-正在查找除内部字符(本例中为>,而*表示无限次)内的字符。
  • ?!-正在查找除字符串以外的任何内容,有点类似于[^>],只是用于字符串而不是单个字符。
  • [\ s \ S]-几乎像.一样使用,但允许任何空格(如果标签之间有新行,则也将匹配)。如果您使用的是正则表达式“ s”标志,则可以改用.

与结束标记一起使用的示例: https://regex101.com/r/MGmzrh/1

使用不带结束标记的示例: https://regex101.com/r/MGmzrh/2


Regex101也对我的工作做了一些解释:)

答案 8 :(得分:1)

这段代码可以帮助您轻松删除任何html标签:

import re
string = str(<a href="blah">blah</a>)
replaced_string = re.sub('<a.*href="blah">.*<\/a>','',string) // remember, sub takes 3 arguments.

输出是一个空字符串。

答案 9 :(得分:0)

这是我用了很长时间的扩展方法。

public static class StringExtensions
{
     public static string StripHTML(this string htmlString, string htmlPlaceHolder) {
         const string pattern = @"<(.|\n)*?>";
         string sOut = Regex.Replace(htmlString, pattern, htmlPlaceHolder);
         sOut = sOut.Replace("&nbsp;", String.Empty);
         sOut = sOut.Replace("&amp;", "&");
         sOut = sOut.Replace("&gt;", ">");
         sOut = sOut.Replace("&lt;", "<");
         return sOut;
     }
}

答案 10 :(得分:0)

使用c#中的正则表达式(图像ID执行的图像搜索)

从字符串中删除图像
string PRQ=<td valign=\"top\" style=\"width: 400px;\" align=\"left\"><img id=\"llgo\" src=\"http://test.Logo.png\" alt=\"logo\"></td>

var regex = new Regex("(<img(.+?)id=\"llgo\"(.+?))src=\"([^\"]+)\"");

PRQ = regex.Replace(PRQ, match => match.Groups[1].Value + "");

答案 11 :(得分:0)

为什么不尝试不情愿的量词?     htmlString.replaceAll("<\\S*?>", "")

(这是Java,但主要的是展示这个想法)

答案 12 :(得分:0)

剥离HTML元素(带有/不带有属性)

/<\/?[\w\s]*>|<.+[\W]>/g

这将删除所有HTML元素,并保留文本。即使对于格式错误的HTML元素(即缺少结束标记的元素),此方法也能很好地发挥作用。

Reference and example (示例10)

答案 13 :(得分:-1)

这是我使用简单的正则表达式创建的扩展方法,用于从字符串中删除HTML标记:

/// <summary>
/// Converts an Html string to plain text, and replaces all br tags with line breaks.
/// </summary>
/// <returns></returns>
/// <remarks></remarks>
[Extension()]
public string ToPlainText(string s)
{

    s = s.Replace("<br>", Constants.vbCrLf);
    s = s.Replace("<br />", Constants.vbCrLf);
    s = s.Replace("<br/>", Constants.vbCrLf);


    s = Regex.Replace(s, "<[^>]*>", string.Empty);


    return s;
}

希望有所帮助。