首页 文章

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

提问于
浏览
135

如何使用C#正则表达式替换/删除所有HTML标记,包括尖括号?有人可以帮我提供代码吗?

10 回答

  • 25

    在此URL尝试正则表达式方法: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);
    }
    
  • 78

    如前所述,您不应使用正则表达式来处理XML或HTML文档 . 它们在HTML和XML文档中表现不佳,因为无法以一般方式表达嵌套结构 .

    您可以使用以下内容 .

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

    这适用于大多数情况,但有些情况(例如CDATA包含尖括号),这将无法按预期工作 .

  • -1

    正确的答案是不要那样做,使用HTML Agility Pack .

    编辑添加:

    为了无耻地从jesse的下面的评论中窃取,并且为了避免被指责在这段时间之后没有充分回答这个问题,这里有一个简单,可靠的片段,使用HTML Agility Pack,即使是最不完美的,形式多变的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 . 您可以通过RegEx获得部分途径,但您需要进行人工验证 .

    Html Agility Pack可以为您提供一个强大的解决方案,可以减少手动修复由于天真地将HTML视为无上下文语法而导致的像差的需要 .

    正则表达式可能会在大多数情况下使您获得大部分时间,但在非常常见的情况下会失败 . 如果你能找到一个比HTML Agility Pack更好/更快的解析器,那就去吧,但请不要让世界受到更多破坏的HTML hackery .

  • 37

    问题太广泛,无法明确回答 . 您是在谈论从真实HTML文档中删除所有标记,例如网页?如果是这样,你必须:

    • 删除<!DOCTYPE声明或<?xml prolog(如果存在)

    • 删除所有SGML评论

    • 删除整个HEAD元素

    • 删除所有SCRIPT和STYLE元素

    • 做Grabthar-knows-with FORM和TABLE元素

    • 删除剩余的标签

    • 从CDATA部分删除<![CDATA [和]]>序列,但保留其内容

    这只是我的头脑 - 我相信还有更多 . 一旦你完成了所有这些,你最终会在某些地方一起运行单词,句子和段落,而在其他地方运行大块无用的空白 .

    但是,假设您只使用一个片段,并且只需删除所有标记即可逃脱,这里是我将使用的正则表达式:

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

    在他们自己的替代品中匹配单引号和双引号字符串足以处理属性值中的尖括号问题 . 我没有看到任何需要明确匹配标签内的属性名称和其他内容,如Ryan的答案中的正则表达式;第一个替代方案处理所有这些 .

    如果你想知道那些 (?>...) 构造,它们是atomic groups . 它们使正则表达式更有效率,但更重要的是,它们可以防止失控的回溯,这是你在混合交替和嵌套量词时应该注意的事情,因为我认为这会是一个问题,但我知道如果我不提它,别人会 . ;-)

    当然,这个正则表达式并不完美,但它可能就像你需要的一样好 .

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

    Source

  • 2

    @JasonTrue是正确的,剥离HTML标签不应该通过正则表达式完成 .

    使用HtmlAgilityPack剥离HTML标记非常简单:

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

    我想回应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"
        }
    
  • 3

    用这个..

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

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

    <[^>].+?>
    

    c# .net regex demo
    enter image description here

  • 5

    使用此方法删除标记:

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

相关问题