Xóa các thẻ HTML khỏi chuỗi bao gồm & nbsp trong C #


83

Làm cách nào để xóa tất cả các thẻ HTML bao gồm & nbsp bằng cách sử dụng regex trong C #. Chuỗi của tôi trông giống như

  "<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
Không sử dụng regex, hãy xem HTML Agility Pack. stackoverflow.com/questions/846994/how-to-use-html-agility-pack
Tim

Cảm ơn Tim, nhưng ứng dụng này khá lớn và nguyên vẹn, việc thêm hoặc tải xuống gói agility html sẽ không hoạt động.
hung hăng,

Câu trả lời:


196

Nếu bạn không thể sử dụng giải pháp định hướng phân tích cú pháp HTML để lọc ra các thẻ, đây là một regex đơn giản cho nó.

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

Lý tưởng nhất là bạn nên thực hiện một lần chuyển qua bộ lọc regex xử lý nhiều khoảng trắng như

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

Tôi vẫn chưa thử nghiệm điều này nhiều như tôi sẽ cần, nhưng nó hoạt động tốt hơn tôi mong đợi. Tôi sẽ đăng phương pháp tôi đã viết bên dưới.
Don Rolling

Một trận đấu lười biếng ( <[^>]+?>theo @ David S.) có thể làm cho này một chút nhanh hơn, nhưng chỉ được sử dụng giải pháp này trong một dự án trực tiếp - rất hạnh phúc 1 :)
Cuốn Mã hóa

Regex.Replace (inputHTML, @ "<[^>] +> | & nbsp | \ n;", "") .Trim (); \ n sẽ không bị xóa
Mahesh Malpani

3
Tôi muốn giới thiệu để quảng cáo một không gian chứ không phải là một chuỗi rỗng, chúng ta đang đánh bắt ra không gian thêm bất kỳ cách nàoRegex.Replace(inputHTML, @"<[^>]+>|&nbsp;", " ")
Tauseef

2
@Tauseef Nếu bạn sử dụng một khoảng trắng trong lần gọi thay thế đầu tiên, bạn có thể để lại khoảng trắng mà không có trong dữ liệu đầu vào ban đầu. Giả sử bạn nhận được Sound<b>Cloud</b>như một đầu vào; bạn sẽ kết thúc với Sound Cloudtrong khi lẽ ra nó phải bị loại bỏ SoundCloudvì đó là cách nó được hiển thị trong HTML.
Ravi Thapliyal

31

Tôi đã lấy mã của @Ravi Thapliyal và thực hiện một phương pháp: Nó đơn giản và có thể không làm sạch mọi thứ, nhưng cho đến nay nó đang làm những gì tôi cần.

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

16

Tôi đã sử dụng chức năng này trong một thời gian. Loại bỏ khá nhiều html lộn xộn mà bạn có thể ném vào nó và giữ nguyên văn bản.

        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();
        }

Chỉ để xác nhận: hàm SingleSpacedTrim () thực hiện tương tự như chuỗi noHTMLNormalised = Regex.Replace (noHTML, @ "\ s {2,}", ""); từ câu trả lời của Ravi Thapliyal?
Jimmy

@Jimmy theo như tôi thấy, regex đó không bắt được các tab hoặc dòng mới như SingleSpacedTrim (). Tuy nhiên, đó có thể là một hiệu quả mong muốn, trong trường hợp đó, chỉ cần loại bỏ các trường hợp cần thiết.
David S.

Tốt, nhưng nó dường như cũng thay thế dấu ngoặc kép và dấu ngoặc kép bằng dấu cách trống, mặc dù chúng không có trong danh sách " notOkCharacter ", hoặc tôi thiếu thứ gì đó ở đó? Đây có phải là phần của cuộc họp Giải mã / Mã hóa được gọi ở phần đầu không? Điều gì sẽ là cần thiết để giữ nguyên những ký tự này?
vm370 21/12/16

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

1

Tôi đã sử dụng mã của @RaviThapliyal & @Don Rolling nhưng đã thực hiện một chút sửa đổi. Vì chúng tôi đang thay thế & nbsp bằng chuỗi trống nhưng thay vào đó & nbsp nên được thay thế bằng khoảng trắng, vì vậy đã thêm một bước bổ sung. Nó làm việc cho tôi như một cái duyên.

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;
}

Đã sử dụng & nbps không có dấu chấm phẩy vì nó đang được định dạng bởi Stack Overflow.


0

điều này:

(<.+?> | &nbsp;)

sẽ khớp với bất kỳ thẻ nào hoặc &nbsp;

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

thì x = hello


0

Việc dọn dẹp một tài liệu Html liên quan đến rất nhiều điều phức tạp. Gói này có thể hữu ích: https://github.com/mganss/HtmlSanitizer


Tôi nghĩ rằng nó dễ bị tấn công XSS hơn là bình thường hóa html
Revious

1
@Trước đó, tôi nghĩ bạn đúng. Có thể câu trả lời của tôi không liên quan nhiều đến câu hỏi của OP vì họ không đề cập đến mục đích của việc loại bỏ các thẻ html. Nhưng nếu mục đích là để ngăn chặn các cuộc tấn công, như trong nhiều trường hợp, thì việc sử dụng chất khử trùng đã được phát triển có thể là một cách tiếp cận tốt hơn. BTW Tôi không biết ý nghĩa của việc chuẩn hóa html là gì.
Ehsan88

0

HTML ở dạng cơ bản chỉ là XML. Bạn có thể phân tích cú pháp văn bản của mình trong một đối tượng XmlDocument và trên phần tử gốc gọi InnerText để trích xuất văn bản. Điều này sẽ loại bỏ tất cả các thẻ HTML dưới mọi hình thức và cũng xử lý các ký tự đặc biệt như & lt; & nbsp; tất cả trong một lần.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.