Làm cách nào để chuyển Html sang văn bản thuần túy?


98

Tôi có các đoạn mã Html được lưu trữ trong một bảng. Không phải toàn bộ trang, không có thẻ hoặc tương tự, chỉ là định dạng cơ bản.

Tôi muốn có thể hiển thị Html đó chỉ dưới dạng văn bản, không có định dạng , trên một trang nhất định (thực tế chỉ là 30 - 50 ký tự đầu tiên nhưng đó là một chút dễ dàng).

Làm cách nào để đặt "văn bản" trong Html đó thành một chuỗi dưới dạng văn bản thẳng?

Vì vậy, đoạn mã này.

<b>Hello World.</b><br/><p><i>Is there anyone out there?</i><p>

Trở thành:

Chào thế giới. Có ai ra khỏi đó?


Bạn có thể muốn sử dụng SgmlReader. code.msdn.microsoft.com/SgmlReader
Leonardo Herrera

Có một số mã khá đơn giản và dễ hiểu để chuyển đổi HTML sang văn bản thuần túy tại blackbeltcoder.com/Articles/strings/convert-html-to-text .
Jonathan Wood

Đây là câu trả lời đúng cho những gì tôi cần - cảm ơn!
Shaul Behr

Có một số gợi ý hay từ W3C ở đây: w3.org/Tools/html2things.html
Rich

4
Làm cách nào để đánh dấu một câu hỏi là trùng lặp với một câu hỏi đã được hỏi 6 tháng sau? Có vẻ một chút lạc hậu ...
Stuart Helwig

Câu trả lời:


27

Nếu bạn đang nói về việc loại bỏ thẻ, nó tương đối dễ hiểu nếu bạn không phải lo lắng về những thứ như <script>thẻ. Nếu tất cả những gì bạn cần làm là hiển thị văn bản mà không có thẻ, bạn có thể thực hiện điều đó với biểu thức chính quy:

<[^>]*>

Nếu bạn phải lo lắng về <script>các thẻ và những thứ tương tự thì bạn sẽ cần một thứ gì đó mạnh mẽ hơn một chút sau đó là biểu thức chính quy vì bạn cần theo dõi trạng thái, giống như Ngữ pháp không có ngữ cảnh (CFG). Mặc dù bạn có thể thực hiện được nó với kết hợp 'Trái sang phải' hoặc không tham lam.

Nếu bạn có thể sử dụng cụm từ thông dụng, có rất nhiều trang web có thông tin tốt:

Nếu bạn cần hành vi phức tạp hơn của CFG, tôi khuyên bạn nên sử dụng công cụ của bên thứ ba, rất tiếc là tôi không biết công cụ nào tốt để giới thiệu.


3
Bạn cũng phải lo lắng về> giá trị thuộc tính, nhận xét, PI / CDATA trong XML và các dạng sai phổ biến khác nhau trong HTML kế thừa. Nói chung [X] [HT] ML không thể phân tích cú pháp với regexps.
bobince

11
Đây là một phương pháp khủng khiếp để làm điều đó. Cách chính xác là phân tích cú pháp HTML bằng lib và duyệt qua nội dung chỉ có trong danh sách cho phép của dom.
usr

2
@usr: Phần bạn đang đề cập đến là phần CFG của câu trả lời. Regex có thể được sử dụng để rút thẻ nhanh chóng và bẩn thỉu, nó có những điểm yếu nhưng nó nhanh chóng và dễ dàng. Để phân tích cú pháp phức tạp hơn, hãy sử dụng công cụ dựa trên CFG (theo cách nói của bạn là lib tạo DOM). Tôi chưa thực hiện các bài kiểm tra nhưng tôi đánh cược rằng phân tích cú pháp DOM chậm hơn so với tước regex, trong trường hợp hiệu suất cần được xem xét.
vfilby

1
@vfilby, cuộc tấn công đầu tiên nghĩ đến là viết "<div id = \" "(cú pháp c # string). Lưu ý rằng thiếu dấu ngoặc kép cuối và thiếu dấu ngoặc nhọn. Tôi đoán điều này sẽ gây nhầm lẫn cho trình duyệt và làm mất cân bằng cấu trúc thẻ. bạn nghĩ gì về cuộc tấn công này? Bạn có thể chắc chắn rằng nó không bao giờ hoạt động không? Khó chịu.
usr

1
@vfilby, không quan trọng nếu lib phân tích cú pháp bị nhầm lẫn hay không. Tất cả những gì bạn cần làm là lấy DOM từ nó (bất kỳ DOM nào) và chỉ xuất các thành phần thuộc danh sách trắng. Điều này luôn an toàn, không quan trọng DOM được phân tích cú pháp trông như thế nào. Ngoài ra, tôi đã nói với bạn nhiều ví dụ mà phương pháp "đơn giản" của bạn sẽ không xóa được thẻ.
usr

95

HtmlAgilityPack mã nguồn mở và miễn phí có một trong các mẫu của nó một phương pháp chuyển đổi từ HTML sang văn bản thuần túy.

var plainText = HtmlUtilities.ConvertToPlainText(string html);

Cung cấp cho nó một chuỗi HTML như

<b>hello, <i>world!</i></b>

Và bạn sẽ nhận được một kết quả văn bản thuần túy như:

hello world!

10
Tôi đã sử dụng HtmlAgilityPack trước đây nhưng tôi không thể thấy bất kỳ tham chiếu nào đến ConvertToPlainText. Bạn có thể cho tôi biết tôi có thể tìm thấy nó ở đâu không?
horatio

8
Horatio, nó được bao gồm trong một trong những mẫu mà đi kèm với HtmlAgilityPack: htmlagilitypack.codeplex.com/sourcecontrol/changeset/view/...
Giu-đa Gabriel Himango

5
Trên thực tế, không có một phương pháp tích hợp nào cho việc này trong Gói Nhanh nhẹn. Những gì bạn đã liên kết đến là một ví dụ sử dụng Gói linh hoạt để xem qua cây nút, xóa scriptstyle gắn thẻ và viết văn bản bên trong của các phần tử khác vào chuỗi đầu ra. Tôi nghi ngờ nó đã vượt qua nhiều thử nghiệm với đầu vào thế giới thực.
Lou

3
Ai đó có thể vui lòng cung cấp mã hoạt động, thay vì các liên kết đến các mẫu cần được trang bị thêm để hoạt động bình thường không?
Eric K

5
Hiện có thể tìm thấy mẫu tại đây: github.com/ceee/ReadSharp/blob/master/ReadSharp/…
StuartQ

51

Tôi không thể sử dụng HtmlAgilityPack, vì vậy tôi đã viết một giải pháp tốt nhất thứ hai cho chính mình

private static string HtmlToPlainText(string html)
{
    const string tagWhiteSpace = @"(>|$)(\W|\n|\r)+<";//matches one or more (white space or line breaks) between '>' and '<'
    const string stripFormatting = @"<[^>]*(>|$)";//match any character between '<' and '>', even when end tag is missing
    const string lineBreak = @"<(br|BR)\s{0,1}\/{0,1}>";//matches: <br>,<br/>,<br />,<BR>,<BR/>,<BR />
    var lineBreakRegex = new Regex(lineBreak, RegexOptions.Multiline);
    var stripFormattingRegex = new Regex(stripFormatting, RegexOptions.Multiline);
    var tagWhiteSpaceRegex = new Regex(tagWhiteSpace, RegexOptions.Multiline);

    var text = html;
    //Decode html specific characters
    text = System.Net.WebUtility.HtmlDecode(text); 
    //Remove tag whitespace/line breaks
    text = tagWhiteSpaceRegex.Replace(text, "><");
    //Replace <br /> with line breaks
    text = lineBreakRegex.Replace(text, Environment.NewLine);
    //Strip formatting
    text = stripFormattingRegex.Replace(text, string.Empty);

    return text;
}

2
& lt; blabla & gt; đã được phân tích cú pháp nên tôi đã di chuyển văn bản = System.Net.WebUtility.HtmlDecode (văn bản); xuống đáy của phương pháp này
Luuk

1
Điều này thật tuyệt, tôi cũng đã thêm một bộ tụ đa không gian vì html có thể đã được tạo từ CMS: var spaceRegex = new Regex ("[] {2,}", RegexOptions.None);
Enkode

Đôi khi, trong mã html có dòng mới của người lập trình (không thể nhìn thấy dòng mới trong bình luận, vì vậy tôi hiển thị nó với [dòng mới], như: <br> Tôi [dòng mới] bỏ lỡ [dòng mới] bạn <br > Vì vậy, nó giả sử để hiển thị: "Em nhớ anh", nhưng nó cho thấy tôi [dòng mới] bỏ lỡ [dòng mới] bạn này làm cho giao diện văn bản đơn giản đau đớn bạn có biết làm thế nào để sửa chữa..?
123iamking

@ 123iamking bạn có thể sử dụng nó trước khi trả về văn bản; : text.Replace ("[dòng mới]", "\ n");
Eslam Badawy,

Tôi đang sử dụng điều này và nhận ra rằng đôi khi nó để lại '>' ở đầu chuỗi. Giải pháp khác áp dụng regex <[^>] *> hoạt động tốt.
Etienne Charland

20

HTTPUtility.HTMLEncode()có nghĩa là để xử lý mã hóa các thẻ HTML dưới dạng chuỗi. Nó đảm nhận tất cả các công việc nặng nhọc cho bạn. Từ Tài liệu MSDN :

Nếu các ký tự như khoảng trống và dấu câu được chuyển trong luồng HTTP, chúng có thể bị hiểu sai ở đầu nhận. Mã hóa HTML chuyển đổi các ký tự không được phép trong HTML thành các ký tự-thực thể tương đương; Giải mã HTML đảo ngược mã hóa. Ví dụ, khi nhúng vào trong một khối văn bản, các nhân vật <>, được giải mã theo &lt;&gt;cho HTTP truyền.

HTTPUtility.HTMLEncode()phương pháp, chi tiết tại đây :

public static void HtmlEncode(
  string s,
  TextWriter output
)

Sử dụng:

String TestString = "This is a <Test String>.";
StringWriter writer = new StringWriter();
Server.HtmlEncode(TestString, writer);
String EncodedString = writer.ToString();

Một câu trả lời thực sự tốt George cảm ơn, nó cũng nêu bật cách tôi hỏi câu hỏi lần đầu tiên kém như thế nào. Lấy làm tiếc.
Stuart Helwig

html nhanh nhẹn gói là ra ngày và không được hỗ trợ html5
abzarak

10

Để thêm vào câu trả lời của vfilby, bạn chỉ có thể thực hiện thay thế RegEx trong mã của mình; không có lớp mới nào là cần thiết. Trong trường hợp những người mới khác như tôi tình cờ gặp câu hỏi này.

using System.Text.RegularExpressions;

Sau đó...

private string StripHtml(string source)
{
        string output;

        //get rid of HTML tags
        output = Regex.Replace(source, "<[^>]*>", string.Empty);

        //get rid of multiple blank lines
        output = Regex.Replace(output, @"^\s*$\n", string.Empty, RegexOptions.Multiline);

        return output;
}

19
KHÔNG TỐT! Điều này có thể bị lừa để chứa tập lệnh bằng cách bỏ qua dấu ngoặc nhọn đóng. CÁC BẠN, đừng bao giờ đưa vào danh sách đen. Bạn không thể khử trùng đầu vào bằng cách đưa vào danh sách đen. Điều đó là sai.
usr

7

Quy trình ba bước để chuyển đổi HTML thành văn bản thuần túy

Đầu tiên bạn cần cài đặt gói Nuget cho HtmlAgilityPack Thứ hai tạo lớp này

public class HtmlToText
{
    public HtmlToText()
    {
    }

    public string Convert(string path)
    {
        HtmlDocument doc = new HtmlDocument();
        doc.Load(path);

        StringWriter sw = new StringWriter();
        ConvertTo(doc.DocumentNode, sw);
        sw.Flush();
        return sw.ToString();
    }

    public string ConvertHtml(string html)
    {
        HtmlDocument doc = new HtmlDocument();
        doc.LoadHtml(html);

        StringWriter sw = new StringWriter();
        ConvertTo(doc.DocumentNode, sw);
        sw.Flush();
        return sw.ToString();
    }

    private void ConvertContentTo(HtmlNode node, TextWriter outText)
    {
        foreach(HtmlNode subnode in node.ChildNodes)
        {
            ConvertTo(subnode, outText);
        }
    }

    public void ConvertTo(HtmlNode node, TextWriter outText)
    {
        string html;
        switch(node.NodeType)
        {
            case HtmlNodeType.Comment:
                // don't output comments
                break;

            case HtmlNodeType.Document:
                ConvertContentTo(node, outText);
                break;

            case HtmlNodeType.Text:
                // script and style must not be output
                string parentName = node.ParentNode.Name;
                if ((parentName == "script") || (parentName == "style"))
                    break;

                // get text
                html = ((HtmlTextNode)node).Text;

                // is it in fact a special closing node output as text?
                if (HtmlNode.IsOverlappedClosingElement(html))
                    break;

                // check the text is meaningful and not a bunch of whitespaces
                if (html.Trim().Length > 0)
                {
                    outText.Write(HtmlEntity.DeEntitize(html));
                }
                break;

            case HtmlNodeType.Element:
                switch(node.Name)
                {
                    case "p":
                        // treat paragraphs as crlf
                        outText.Write("\r\n");
                        break;
                }

                if (node.HasChildNodes)
                {
                    ConvertContentTo(node, outText);
                }
                break;
        }
    }
}

Bằng cách sử dụng lớp trên với tham chiếu đến câu trả lời của Judah Himango

Thứ ba, bạn cần tạo Đối tượng của lớp trên và Sử dụng ConvertHtml(HTMLContent)Phương pháp để chuyển đổi HTML thành Văn bản thuần túy hơn làConvertToPlainText(string html);

HtmlToText htt=new HtmlToText();
var plainText = htt.ConvertHtml(HTMLContent);

tôi có thể bỏ qua chuyển đổi liên kết trong html. tôi cần giữ liên kết trong html khi chuyển đổi sang văn bản?
coder771

6

Nó có hạn chế là không thu gọn khoảng trắng nội tuyến dài, nhưng nó chắc chắn là di động và tôn trọng bố cục như trình duyệt web.

static string HtmlToPlainText(string html) {
  string buf;
  string block = "address|article|aside|blockquote|canvas|dd|div|dl|dt|" +
    "fieldset|figcaption|figure|footer|form|h\\d|header|hr|li|main|nav|" +
    "noscript|ol|output|p|pre|section|table|tfoot|ul|video";

  string patNestedBlock = $"(\\s*?</?({block})[^>]*?>)+\\s*";
  buf = Regex.Replace(html, patNestedBlock, "\n", RegexOptions.IgnoreCase);

  // Replace br tag to newline.
  buf = Regex.Replace(buf, @"<(br)[^>]*>", "\n", RegexOptions.IgnoreCase);

  // (Optional) remove styles and scripts.
  buf = Regex.Replace(buf, @"<(script|style)[^>]*?>.*?</\1>", "", RegexOptions.Singleline);

  // Remove all tags.
  buf = Regex.Replace(buf, @"<[^>]*(>|$)", "", RegexOptions.Multiline);

  // Replace HTML entities.
  buf = WebUtility.HtmlDecode(buf);
  return buf;
}

4

Không có phương thức có tên 'ConvertToPlainText' trong HtmlAgilityPack nhưng bạn có thể chuyển đổi chuỗi html thành chuỗi CLEAR bằng:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlString);
var textString = doc.DocumentNode.InnerText;
Regex.Replace(textString , @"<(.|n)*?>", string.Empty).Replace("&nbsp", "");

Đó là hiệu quả cho tôi. NHƯNG TÔI KHÔNG TÌM ĐƯỢC PHƯƠNG PHÁP CÓ TÊN 'ConvertToPlainText' TRONG 'HtmlAgilityPack'.


3

Tôi nghĩ cách dễ nhất là tạo phương thức mở rộng 'chuỗi' (dựa trên những gì người dùng Richard đã đề xuất):

using System;
using System.Text.RegularExpressions;

public static class StringHelpers
{
    public static string StripHTML(this string HTMLText)
        {
            var reg = new Regex("<[^>]+>", RegexOptions.IgnoreCase);
            return reg.Replace(HTMLText, "");
        }
}

Sau đó, chỉ cần sử dụng phương thức mở rộng này trên bất kỳ biến 'chuỗi' nào trong chương trình của bạn:

var yourHtmlString = "<div class=\"someclass\"><h2>yourHtmlText</h2></span>";
var yourTextString = yourHtmlString.StripHTML();

Tôi sử dụng phương pháp mở rộng này để chuyển đổi các nhận xét có định dạng html thành văn bản thuần túy để nó được hiển thị chính xác trên một báo cáo pha lê và nó hoạt động hoàn hảo!


3

Cách đơn giản nhất mà tôi tìm thấy:

HtmlFilter.ConvertToPlainText(html);

Lớp HtmlFilter nằm trong Microsoft.TeamFoundation.WorkItemTracking.Controls.dll

Bạn có thể tìm thấy dll trong thư mục như sau:% ProgramFiles% \ Common Files \ microsoft shared \ Team Foundation Server \ 14.0 \

Trong VS 2015, dll cũng yêu cầu tham chiếu đến Microsoft.TeamFoundation.WorkItemTracking.Common.dll, nằm trong cùng một thư mục.


nó có chăm sóc các thẻ script và nó có định dạng là in nghiêng đậm, v.v. không?
Samra

Giới thiệu sự phụ thuộc nền tảng nhóm để chuyển đổi html sang văn bản thuần túy, rất đáng ...
ViRuSTriNiTy

2

Nếu bạn có dữ liệu có các thẻ HTML và bạn muốn hiển thị nó để mọi người có thể XEM các thẻ, hãy sử dụng HttpServerUtility :: HtmlEncode.

Nếu bạn có dữ liệu có các thẻ HTML trong đó và bạn muốn người dùng nhìn thấy các thẻ được hiển thị, thì hãy hiển thị văn bản như hiện tại. Nếu văn bản đại diện cho toàn bộ trang web, hãy sử dụng IFRAME cho nó.

Nếu bạn có dữ liệu có thẻ HTML và bạn muốn loại bỏ các thẻ và chỉ hiển thị văn bản chưa được định dạng, hãy sử dụng biểu thức chính quy.


trong php có một hàm được gọi là Striptags () có thể bạn có một cái gì đó tương tự
markus

"sử dụng một biểu thức chính quy" KHÔNG! Đây sẽ là danh sách đen. Bạn chỉ có thể an toàn khi lập danh sách trắng. Ví dụ, bạn có nhớ rằng style attibute có thể chứa "background: url ('javascript: ...');" không? tất nhiên là không, tôi cũng sẽ không có. Đó là lý do tại sao danh sách đen không hoạt động.
usr

2

Tôi đã đối mặt với vấn đề tương tự và tìm ra giải pháp tốt nhất. Mã dưới đây hoạt động hoàn hảo cho tôi.

  private string ConvertHtml_Totext(string source)
    {
     try
      {
      string result;

    // Remove HTML Development formatting
    // Replace line breaks with space
    // because browsers inserts space
    result = source.Replace("\r", " ");
    // Replace line breaks with space
    // because browsers inserts space
    result = result.Replace("\n", " ");
    // Remove step-formatting
    result = result.Replace("\t", string.Empty);
    // Remove repeating spaces because browsers ignore them
    result = System.Text.RegularExpressions.Regex.Replace(result,
                                                          @"( )+", " ");

    // Remove the header (prepare first by clearing attributes)
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*head([^>])*>","<head>",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"(<( )*(/)( )*head( )*>)","</head>",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(<head>).*(</head>)",string.Empty,
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // remove all scripts (prepare first by clearing attributes)
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*script([^>])*>","<script>",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"(<( )*(/)( )*script( )*>)","</script>",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    //result = System.Text.RegularExpressions.Regex.Replace(result,
    //         @"(<script>)([^(<script>\.</script>)])*(</script>)",
    //         string.Empty,
    //         System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"(<script>).*(</script>)",string.Empty,
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // remove all styles (prepare first by clearing attributes)
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*style([^>])*>","<style>",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"(<( )*(/)( )*style( )*>)","</style>",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(<style>).*(</style>)",string.Empty,
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // insert tabs in spaces of <td> tags
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*td([^>])*>","\t",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // insert line breaks in places of <BR> and <LI> tags
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*br( )*>","\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*li( )*>","\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // insert line paragraphs (double line breaks) in place
    // if <P>, <DIV> and <TR> tags
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*div([^>])*>","\r\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*tr([^>])*>","\r\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<( )*p([^>])*>","\r\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // Remove remaining tags like <a>, links, images,
    // comments etc - anything that's enclosed inside < >
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"<[^>]*>",string.Empty,
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // replace special characters:
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @" "," ",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&bull;"," * ",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&lsaquo;","<",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&rsaquo;",">",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&trade;","(tm)",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&frasl;","/",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&lt;","<",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&gt;",">",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&copy;","(c)",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&reg;","(r)",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    // Remove all others. More can be added, see
    // http://hotwired.lycos.com/webmonkey/reference/special_characters/
    result = System.Text.RegularExpressions.Regex.Replace(result,
             @"&(.{2,6});", string.Empty,
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // for testing
    //System.Text.RegularExpressions.Regex.Replace(result,
    //       this.txtRegex.Text,string.Empty,
    //       System.Text.RegularExpressions.RegexOptions.IgnoreCase);

    // make line breaking consistent
    result = result.Replace("\n", "\r");

    // Remove extra line breaks and tabs:
    // replace over 2 breaks with 2 and over 4 tabs with 4.
    // Prepare first to remove any whitespaces in between
    // the escaped characters and remove redundant tabs in between line breaks
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(\r)( )+(\r)","\r\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(\t)( )+(\t)","\t\t",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(\t)( )+(\r)","\t\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(\r)( )+(\t)","\r\t",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    // Remove redundant tabs
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(\r)(\t)+(\r)","\r\r",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    // Remove multiple tabs following a line break with just one tab
    result = System.Text.RegularExpressions.Regex.Replace(result,
             "(\r)(\t)+","\r\t",
             System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    // Initial replacement target string for line breaks
    string breaks = "\r\r\r";
    // Initial replacement target string for tabs
    string tabs = "\t\t\t\t\t";
    for (int index=0; index<result.Length; index++)
    {
        result = result.Replace(breaks, "\r\r");
        result = result.Replace(tabs, "\t\t\t\t");
        breaks = breaks + "\r";
        tabs = tabs + "\t";
    }

    // That's it.
    return result;
}
catch
{
    MessageBox.Show("Error");
    return source;
}

}

Các ký tự thoát như \ n và \ r phải được xóa trước vì chúng khiến regex không hoạt động như mong đợi.

Hơn nữa, để làm cho chuỗi kết quả hiển thị chính xác trong hộp văn bản, người ta có thể cần phải tách nó ra và đặt thuộc tính Lines của hộp văn bản thay vì gán cho thuộc tính Văn bản.

this.txtResult.Lines = StripHTML (this.txtSource.Text) .Split ("\ r" .ToCharArray ());

Nguồn: https://www.codeproject.com/Articles/11902/Convert-HTML-to-Plain-Text-2


0

Phụ thuộc vào ý bạn của "html". Trường hợp phức tạp nhất sẽ là các trang web hoàn chỉnh. Đó cũng là cách dễ xử lý nhất vì bạn có thể sử dụng trình duyệt web ở chế độ văn bản. Xem bài viết Wikipedia liệt kê các trình duyệt web, bao gồm các trình duyệt chế độ văn bản. Lynx có lẽ được biết đến nhiều nhất, nhưng một trong những loại khác có thể tốt hơn cho nhu cầu của bạn.


khi anh ấy nói "Tôi có các đoạn mã Html được lưu trữ trong bảng."
M lúc

0

Đây là giải pháp của tôi:

public string StripHTML(string html)
{
    var regex = new Regex("<[^>]+>", RegexOptions.IgnoreCase);
    return System.Web.HttpUtility.HtmlDecode((regex.Replace(html, "")));
}

Thí dụ:

StripHTML("<p class='test' style='color:red;'>Here is my solution:</p>");
// output -> Here is my solution:

0

Tôi đã có câu hỏi tương tự, chỉ là html của tôi có bố cục đơn giản đã biết trước, như:

<DIV><P>abc</P><P>def</P></DIV>

Vì vậy, tôi đã kết thúc bằng cách sử dụng mã đơn giản như vậy:

string.Join (Environment.NewLine, XDocument.Parse (html).Root.Elements ().Select (el => el.Value))

Kết quả đầu ra:

abc
def

0

Không viết nhưng sử dụng:

using HtmlAgilityPack;
using System;
using System.IO;
using System.Text.RegularExpressions;

namespace foo {
  //small but important modification to class https://github.com/zzzprojects/html-agility-pack/blob/master/src/Samples/Html2Txt/HtmlConvert.cs
  public static class HtmlToText {

    public static string Convert(string path) {
      HtmlDocument doc = new HtmlDocument();
      doc.Load(path);
      return ConvertDoc(doc);
    }

    public static string ConvertHtml(string html) {
      HtmlDocument doc = new HtmlDocument();
      doc.LoadHtml(html);
      return ConvertDoc(doc);
    }

    public static string ConvertDoc(HtmlDocument doc) {
      using (StringWriter sw = new StringWriter()) {
        ConvertTo(doc.DocumentNode, sw);
        sw.Flush();
        return sw.ToString();
      }
    }

    internal static void ConvertContentTo(HtmlNode node, TextWriter outText, PreceedingDomTextInfo textInfo) {
      foreach (HtmlNode subnode in node.ChildNodes) {
        ConvertTo(subnode, outText, textInfo);
      }
    }
    public static void ConvertTo(HtmlNode node, TextWriter outText) {
      ConvertTo(node, outText, new PreceedingDomTextInfo(false));
    }
    internal static void ConvertTo(HtmlNode node, TextWriter outText, PreceedingDomTextInfo textInfo) {
      string html;
      switch (node.NodeType) {
        case HtmlNodeType.Comment:
          // don't output comments
          break;
        case HtmlNodeType.Document:
          ConvertContentTo(node, outText, textInfo);
          break;
        case HtmlNodeType.Text:
          // script and style must not be output
          string parentName = node.ParentNode.Name;
          if ((parentName == "script") || (parentName == "style")) {
            break;
          }
          // get text
          html = ((HtmlTextNode)node).Text;
          // is it in fact a special closing node output as text?
          if (HtmlNode.IsOverlappedClosingElement(html)) {
            break;
          }
          // check the text is meaningful and not a bunch of whitespaces
          if (html.Length == 0) {
            break;
          }
          if (!textInfo.WritePrecedingWhiteSpace || textInfo.LastCharWasSpace) {
            html = html.TrimStart();
            if (html.Length == 0) { break; }
            textInfo.IsFirstTextOfDocWritten.Value = textInfo.WritePrecedingWhiteSpace = true;
          }
          outText.Write(HtmlEntity.DeEntitize(Regex.Replace(html.TrimEnd(), @"\s{2,}", " ")));
          if (textInfo.LastCharWasSpace = char.IsWhiteSpace(html[html.Length - 1])) {
            outText.Write(' ');
          }
          break;
        case HtmlNodeType.Element:
          string endElementString = null;
          bool isInline;
          bool skip = false;
          int listIndex = 0;
          switch (node.Name) {
            case "nav":
              skip = true;
              isInline = false;
              break;
            case "body":
            case "section":
            case "article":
            case "aside":
            case "h1":
            case "h2":
            case "header":
            case "footer":
            case "address":
            case "main":
            case "div":
            case "p": // stylistic - adjust as you tend to use
              if (textInfo.IsFirstTextOfDocWritten) {
                outText.Write("\r\n");
              }
              endElementString = "\r\n";
              isInline = false;
              break;
            case "br":
              outText.Write("\r\n");
              skip = true;
              textInfo.WritePrecedingWhiteSpace = false;
              isInline = true;
              break;
            case "a":
              if (node.Attributes.Contains("href")) {
                string href = node.Attributes["href"].Value.Trim();
                if (node.InnerText.IndexOf(href, StringComparison.InvariantCultureIgnoreCase) == -1) {
                  endElementString = "<" + href + ">";
                }
              }
              isInline = true;
              break;
            case "li":
              if (textInfo.ListIndex > 0) {
                outText.Write("\r\n{0}.\t", textInfo.ListIndex++);
              } else {
                outText.Write("\r\n*\t"); //using '*' as bullet char, with tab after, but whatever you want eg "\t->", if utf-8 0x2022
              }
              isInline = false;
              break;
            case "ol":
              listIndex = 1;
              goto case "ul";
            case "ul": //not handling nested lists any differently at this stage - that is getting close to rendering problems
              endElementString = "\r\n";
              isInline = false;
              break;
            case "img": //inline-block in reality
              if (node.Attributes.Contains("alt")) {
                outText.Write('[' + node.Attributes["alt"].Value);
                endElementString = "]";
              }
              if (node.Attributes.Contains("src")) {
                outText.Write('<' + node.Attributes["src"].Value + '>');
              }
              isInline = true;
              break;
            default:
              isInline = true;
              break;
          }
          if (!skip && node.HasChildNodes) {
            ConvertContentTo(node, outText, isInline ? textInfo : new PreceedingDomTextInfo(textInfo.IsFirstTextOfDocWritten) { ListIndex = listIndex });
          }
          if (endElementString != null) {
            outText.Write(endElementString);
          }
          break;
      }
    }
  }
  internal class PreceedingDomTextInfo {
    public PreceedingDomTextInfo(BoolWrapper isFirstTextOfDocWritten) {
      IsFirstTextOfDocWritten = isFirstTextOfDocWritten;
    }
    public bool WritePrecedingWhiteSpace { get; set; }
    public bool LastCharWasSpace { get; set; }
    public readonly BoolWrapper IsFirstTextOfDocWritten;
    public int ListIndex { get; set; }
  }
  internal class BoolWrapper {
    public BoolWrapper() { }
    public bool Value { get; set; }
    public static implicit operator bool(BoolWrapper boolWrapper) {
      return boolWrapper.Value;
    }
    public static implicit operator BoolWrapper(bool boolWrapper) {
      return new BoolWrapper { Value = boolWrapper };
    }
  }
}

0

Tôi nghĩ nó có một câu trả lời đơn giản:

public string RemoveHTMLTags(string HTMLCode)
{
    string str=System.Text.RegularExpressions.Regex.Replace(HTMLCode, "<[^>]*>", "");
    return str;
}

0

Đối với bất kỳ ai đang tìm kiếm giải pháp chính xác cho câu hỏi OP về chữ viết tắt văn bản của một tài liệu html nhất định, không có dòng mới và thẻ HTML, vui lòng tìm giải pháp bên dưới.

Giống như với mọi giải pháp được đề xuất, có một số giả định với đoạn mã dưới đây:

  • script hoặc thẻ style không được chứa script và thẻ style như một phần của script
  • chỉ các phần tử nội tuyến chính sẽ được nội tuyến mà không có khoảng trắng, tức là he<span>ll</span>onên xuất ra hello. Danh sách các thẻ nội tuyến: https://www.w3schools.com/htmL/html_blocks.asp

Xem xét ở trên, phần mở rộng chuỗi sau với các biểu thức chính quy đã biên dịch sẽ xuất ra văn bản thuần túy dự kiến ​​liên quan đến các ký tự thoát html và null trên đầu vào null.

public static class StringExtensions
{
    public static string ConvertToPlain(this string html)
    {
        if (html == null)
        {
            return html;
        }

        html = scriptRegex.Replace(html, string.Empty);
        html = inlineTagRegex.Replace(html, string.Empty);
        html = tagRegex.Replace(html, " ");
        html = HttpUtility.HtmlDecode(html);
        html = multiWhitespaceRegex.Replace(html, " ");

        return html.Trim();
    }

    private static readonly Regex inlineTagRegex = new Regex("<\\/?(a|span|sub|sup|b|i|strong|small|big|em|label|q)[^>]*>", RegexOptions.Compiled | RegexOptions.Singleline);
    private static readonly Regex scriptRegex = new Regex("<(script|style)[^>]*?>.*?</\\1>", RegexOptions.Compiled | RegexOptions.Singleline);
    private static readonly Regex tagRegex = new Regex("<[^>]+>", RegexOptions.Compiled | RegexOptions.Singleline);
    private static readonly Regex multiWhitespaceRegex = new Regex("\\s+", RegexOptions.Compiled | RegexOptions.Singleline);
}

-4

public static string StripTags2 (string html) {return html.Replace ("<", "<"). Replace (">", ">"); }

Bằng cách này, bạn thoát tất cả "<" và ">" trong một chuỗi. Đây có phải là những gì bạn muốn?


...Ah. Giờ thì câu trả lời (cùng với cách giải thích câu hỏi mơ hồ) đã hoàn toàn thay đổi, tôi sẽ chọn nits khi thiếu & amp; mã hóa thay thế. ;-)
bobince

2
Tôi không nghĩ rằng nên phát minh lại bánh xe - đặc biệt là khi bánh xe của bạn có hình vuông. Bạn nên sử dụng HTMLEncode để thay thế.
Kramii
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.