使用 C # 正则表达式删除 HTML 标记

如何使用 C # 正则表达式替换/删除所有 HTML 标记,包括尖括号? 有人能帮我解开密码吗?

219758 次浏览
Regex regex = new Regex(@"</?\w+((\s+\w+(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+))?)+\s*|\s*)/?>", RegexOptions.Singleline);

来源

如前所述,不应使用正则表达式处理 XML 或 HTML 文档。它们不能很好地处理 HTML 和 XML 文档,因为无法以通用的方式表示嵌套结构。

您可以使用以下内容。

String result = Regex.Replace(htmlDocument, @"<[^>]*>", String.Empty);

这在大多数情况下都可以工作,但是在某些情况下(例如包含尖括号的 CDATA) ,这不会像预期的那样工作。

正确的答案是不要这样做,使用 HTML 敏捷包

编辑补充:

为了厚颜无耻地剽窃 Jesse 下面的评论,并避免被指责一直以来没有充分回答这个问题,这里有一个使用 HTML 敏捷包的简单、可靠的代码片段,它甚至可以处理格式最不完美、反复无常的 HTML 片段:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(Properties.Resources.HtmlContents);
var text = doc.DocumentNode.SelectNodes("//body//text()").Select(node => node.InnerText);
StringBuilder output = new StringBuilder();
foreach (string line in text)
{
output.AppendLine(line);
}
string textOnly = HttpUtility.HtmlDecode(output.ToString());

使用正则表达式解析 HTML 的情况很少,因为如果没有上下文感知,HTML 就无法正确解析,即使在非传统的正则表达式引擎中提供上下文感知也是非常痛苦的。使用正则表达式可以部分实现,但是需要进行手动验证。

HTML 敏捷包可以为你提供一个健壮的解决方案,这将减少手动修复可能导致畸变的需要,天真地把 HTML 当作一个上下文无关文法。

正则表达式可能在大多数情况下获得您想要的大部分内容,但是在非常常见的情况下它会失败。如果你能找到一个比 HTML 敏捷包更好更快的解析器,那就去做吧,但是请不要让世界陷入更多破碎的 HTML 黑客行为。

这个问题过于宽泛,无法明确回答。你是说从一个真实的 HTML 文档中移除所有的标签,比如一个网页?如果是这样,你必须:

  • 删除 < ! DOCTYPE 声明或 < ? xml 序言(如果存在)
  • 删除所有 SGML 注释
  • 移除整个 HEAD 元素
  • 删除所有脚本和样式元素
  • 使用 FORM 和 TABLE 元素做 Grabthar-knows-what
  • 删除剩余的标签
  • 从 CDATA 节中删除 < ! [ CDATA [和]] > 序列,但不要管它们的内容

这只是我的第一反应,肯定还有更多。一旦你完成了所有这些工作,你就会在某些地方看到单词、句子和段落,在另一些地方看到大块无用的空白。

但是,假设您只处理一个片段,并且可以简单地删除所有标记,那么我将使用下面的正则表达式:

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

匹配单引号和双引号字符串在它们自己的备选方案中足以处理属性值中的尖括号问题。我认为没有必要像 Ryan 的回答中的 regex 那样显式地匹配属性名和标记中的其他内容; 第一种方法可以处理所有这些内容。

如果你想知道那些 (?>...)构造,它们是 原子团。它们使正则表达式更有效一些,但更重要的是,它们防止失控的回溯,这是您在混合交替和嵌套量词时应该始终注意的东西,就像我所做的那样。我觉得这不是问题,但我知道如果我不提,别人会提的。;-)

当然,这个正则表达式并不完美,但是它可能已经足够好了。

用这个。

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

我想重复 Jason 的回应,尽管有时候您需要天真地解析一些 HTML 并抽出文本内容。

我需要使用一些由富文本编辑器创建的 HTML 来做这件事,总是充满乐趣和游戏。

在这种情况下,您可能需要删除一些标记的内容以及标记本身。

在我的情况下,标签被扔进这个混合。有些人可能会发现我(非常轻微地)不那么幼稚的实现是一个有用的起点。

   /// <summary>
/// Removes all html tags from string and leaves only plain text
/// Removes content of <xml></xml> and <style></style> tags as aim to get text content not markup /meta data.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string HtmlStrip(this string input)
{
input = Regex.Replace(input, "<style>(.|\n)*?</style>",string.Empty);
input = Regex.Replace(input, @"<xml>(.|\n)*?</xml>", string.Empty); // remove all <xml></xml> tags and anything inbetween.
return Regex.Replace(input, @"<(.|\n)*?>", string.Empty); // remove any tags but not there content "<p>bob<span> johnson</span></p>" becomes "bob johnson"
}

@ JasonTrue 是正确的,不应该通过正则表达式来剥离 HTML 标记。

使用 HtmlAgilityPack 去掉 HTML 标记非常简单:

public string StripTags(string input) {
var doc = new HtmlDocument();
doc.LoadHtml(input ?? "");
return doc.DocumentNode.InnerText;
}

在这个 URL 上尝试正则表达式方法: < a href = “ http://www.dotnetperls.com/remove-html-tag”> http://www.dotnetperls.com/remove-html-tags

/// <summary>
/// Remove HTML from string with Regex.
/// </summary>
public static string StripTagsRegex(string source)
{
return Regex.Replace(source, "<.*?>", string.Empty);
}


/// <summary>
/// Compiled regular expression for performance.
/// </summary>
static Regex _htmlRegex = new Regex("<.*?>", RegexOptions.Compiled);


/// <summary>
/// Remove HTML from string with compiled Regex.
/// </summary>
public static string StripTagsRegexCompiled(string source)
{
return _htmlRegex.Replace(source, string.Empty);
}

<[^>]*>中添加 .+?并尝试这个正则表达式(基于 这个) :

<[^>].+?>

C # . net regex demo enter image description here

使用此方法删除标记:

public string From_To(string text, string from, string to)
{
if (text == null)
return null;
string pattern = @"" + from + ".*?" + to;
Regex rx = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
MatchCollection matches = rx.Matches(text);
return matches.Count <= 0 ? text : matches.Cast<Match>().Where(match => !string.IsNullOrEmpty(match.Value)).Aggregate(text, (current, match) => current.Replace(match.Value, ""));
}