从C#中包含&nbsp的字符串中删除HTML标签


83

如何在C#中使用正则表达式删除所有HTML标记,包括&nbsp。我的弦看起来像

  "<div>hello</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div>"

9
不要使用正则表达式,请查看HTML Agility Pack。stackoverflow.com/questions/846994/how-to-use-html-agility-pack
Tim

感谢Tim,但该应用程序很大且完好无损,无法添加或下载html敏捷包。
rampuriyaaa 2013年

Answers:


196

如果您不能使用面向HTML解析器的解决方案来过滤标签,则这里有一个简单的正则表达式。

string noHTML = Regex.Replace(inputHTML, @"<[^>]+>|&nbsp;", "").Trim();

理想情况下,您应该再次通过正则表达式过滤器,该过滤器将多个空格

string noHTMLNormalised = Regex.Replace(noHTML, @"\s{2,}", " ");

我尚未进行所需的测试,但是它比我预期的要好。我将在下面发布我写的方法。
Don Rolling

一次懒惰的比赛(<[^>]+?>按照@David S.进行)可能会使其更快一点,但是只是在一个实时项目中使用了该解决方案-非常高兴+1 :)
Gone Coding

Regex.Replace(inputHTML,@“ <[^>] +> |&nbsp | \ n;”,“”).Trim(); \ n不得到去除
马赫什Malpani

3
我建议添加一个空格而不是一个空字符串,我们会以任何方式捕获多余的空格Regex.Replace(inputHTML, @"<[^>]+>|&nbsp;", " ")
Tauseef

2
@Tauseef如果在第一个replace调用中使用空格,则最终可能会留下原始输入中没有空格的空格。假设您收到Sound<b>Cloud</b>输入信息;您最终Sound Cloud会得到应被剥离的信息,SoundCloud因为那样就可以将其显示为HTML。
拉维·萨普利雅尔

31

我使用了@Ravi Thapliyal的代码,并提出了一个方法:它很简单,可能无法清除所有内容,但到目前为止,它正在执行我需要做的事情。

public static string ScrubHtml(string value) {
    var step1 = Regex.Replace(value, @"<[^>]+>|&nbsp;", "").Trim();
    var step2 = Regex.Replace(step1, @"\s{2,}", " ");
    return step2;
}

16

我已经使用了一段时间了。删除几乎所有您可以扔给它的凌乱的html,并使文本完整无缺。

        private static readonly Regex _tags_ = new Regex(@"<[^>]+?>", RegexOptions.Multiline | RegexOptions.Compiled);

        //add characters that are should not be removed to this regex
        private static readonly Regex _notOkCharacter_ = new Regex(@"[^\w;&#@.:/\\?=|%!() -]", RegexOptions.Compiled);

        public static String UnHtml(String html)
        {
            html = HttpUtility.UrlDecode(html);
            html = HttpUtility.HtmlDecode(html);

            html = RemoveTag(html, "<!--", "-->");
            html = RemoveTag(html, "<script", "</script>");
            html = RemoveTag(html, "<style", "</style>");

            //replace matches of these regexes with space
            html = _tags_.Replace(html, " ");
            html = _notOkCharacter_.Replace(html, " ");
            html = SingleSpacedTrim(html);

            return html;
        }

        private static String RemoveTag(String html, String startTag, String endTag)
        {
            Boolean bAgain;
            do
            {
                bAgain = false;
                Int32 startTagPos = html.IndexOf(startTag, 0, StringComparison.CurrentCultureIgnoreCase);
                if (startTagPos < 0)
                    continue;
                Int32 endTagPos = html.IndexOf(endTag, startTagPos + 1, StringComparison.CurrentCultureIgnoreCase);
                if (endTagPos <= startTagPos)
                    continue;
                html = html.Remove(startTagPos, endTagPos - startTagPos + endTag.Length);
                bAgain = true;
            } while (bAgain);
            return html;
        }

        private static String SingleSpacedTrim(String inString)
        {
            StringBuilder sb = new StringBuilder();
            Boolean inBlanks = false;
            foreach (Char c in inString)
            {
                switch (c)
                {
                    case '\r':
                    case '\n':
                    case '\t':
                    case ' ':
                        if (!inBlanks)
                        {
                            inBlanks = true;
                            sb.Append(' ');
                        }   
                        continue;
                    default:
                        inBlanks = false;
                        sb.Append(c);
                        break;
                }
            }
            return sb.ToString().Trim();
        }

只是为了确认:SingleSpacedTrim()函数与字符串noHTMLNormalized = Regex.Replace(noHTML,@“ \ s {2,}”,“”)的作用相同。从拉维·萨普利雅尔(Ravi Thapliyal)的答案中得出?
2014年

据我所知,@ Jimmy表示,正则表达式不会像SingleSpacedTrim()那样捕获单个制表符或换行符。不过,这可能是理想的效果,在这种情况下,只需根据需要删除案例即可。
David S.

很好,但是它似乎也用空格代替了单引号和双引号,尽管它们不在“ notOkCharacter ”列表中,还是我在那儿缺少了什么?解码/编码方法的这一部分是否在一开始就被调用?要保持这些字符完整,将需要什么?
vm370 '16

4
var noHtml = Regex.Replace(inputHTML, @"<[^>]*(>|$)|&nbsp;|&zwnj;|&raquo;|&laquo;", string.Empty).Trim();

1

我使用了@RaviThapliyal和@Don Rolling的代码,但做了一些修改。由于我们将&nbsp替换为空字符串,而应将&nbsp替换为空格,因此添加了额外的步骤。它对我来说就像一种魅力。

public static string FormatString(string value) {
    var step1 = Regex.Replace(value, @"<[^>]+>", "").Trim();
    var step2 = Regex.Replace(step1, @"&nbsp;", " ");
    var step3 = Regex.Replace(step2, @"\s{2,}", " ");
    return step3;
}

使用不带分号的&nbps,因为它已由堆栈溢出格式化。


0

这个:

(<.+?> | &nbsp;)

将匹配任何标签或 &nbsp;

string regex = @"(<.+?>|&nbsp;)";
var x = Regex.Replace(originalString, regex, "").Trim();

然后x = hello


0

对HTML文档进行消毒涉及很多棘手的事情。该软件包可能会有所帮助:https : //github.com/mganss/HtmlSanitizer


我认为,与标准化HTML相比,它更是XSS攻击
Revious

1
@Revious我认为你是对的。也许我的回答与OP的问题关系不大,因为他们没有提到删除html标签的目的。但是,如果目的是在许多情况下防止攻击,那么使用已经开发的消毒剂可能是更好的方法。顺便说一句,我不知道标准化html是什么意思。
Ehsan88 '19

0

HTML的基本形式就是XML。您可以在XmlDocument对象中解析文本,然后在根元素上调用InnerText提取文本。这将以任何形式去除所有HTML标记,并且还会处理&lt;等特殊字符。&nbsp; 一口气。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.