Как вы конвертируете HTML в обычный текст? - PullRequest
79 голосов
/ 13 ноября 2008

У меня есть фрагменты HTML, хранящиеся в таблице. Не целые страницы, без тегов и т. П., Просто базовое форматирование.

Я хотел бы иметь возможность отображать этот HTML только в виде текста, без форматирования на данной странице (на самом деле это только первые 30-50 символов, но это просто)

Как поместить текст в этот HTML в строку как прямой текст?

Итак, этот кусок кода.

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

становится:

Hello World. Там кто-нибудь есть?

Ответы [ 17 ]

82 голосов
/ 13 июля 2009

Бесплатный и открытый исходный код HtmlAgilityPack содержит в одном из своих примеров метод, который преобразует HTML в простой текст.

var plainText = HtmlUtilities.ConvertToPlainText(string html);

Подайте в HTML-строку, например,

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

И вы получите простой текстовый результат, например:

hello world!
37 голосов
/ 07 мая 2013

Я не мог использовать HtmlAgilityPack, поэтому я написал второе лучшее решение для себя

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;
}
23 голосов
/ 13 ноября 2008

Если вы говорите о разборке тегов, то относительно просто, если вам не нужно беспокоиться о таких вещах, как <script> теги. Если все, что вам нужно сделать, это отобразить текст без тегов, вы можете сделать это с помощью регулярного выражения:

<[^>]*>

Если вам действительно нужно беспокоиться о <script> тегах и тому подобном, то вам понадобится что-то более мощное, чем регулярные выражения, потому что вам нужно отслеживать состояние, что-то вроде контекстно-свободной грамматики (CFG). Хотя вы можете выполнить это с помощью «Слева направо» или не жадного сопоставления.

Если вы можете использовать регулярные выражения, есть много веб-страниц с хорошей информацией:

Если вам нужно более сложное поведение CFG, я бы посоветовал использовать сторонний инструмент, к сожалению, я не знаю, какой из них можно порекомендовать.

20 голосов
/ 13 ноября 2008

HTTPUtility.HTMLEncode() предназначен для обработки кодирующих тегов HTML в виде строк. Он берет на себя всю тяжелую работу за вас. Из документации MSDN :

Если такие символы, как пробелы и знаки препинания, передаются в потоке HTTP, они могут быть неправильно истолкованы на принимающей стороне. Кодировка HTML преобразует символы, которые не разрешены в HTML, в эквиваленты символьной сущности; HTML декодирование меняет кодировку. Например, при включении в блок текста символы < и > кодируются как &lt; и &gt; для передачи по HTTP.

HTTPUtility.HTMLEncode() метод, подробно здесь :

public static void HtmlEncode(
  string s,
  TextWriter output
)

Использование:

String TestString = "This is a <Test String>.";
StringWriter writer = new StringWriter();
Server.HtmlEncode(TestString, writer);
String EncodedString = writer.ToString();
10 голосов
/ 11 марта 2011

Чтобы добавить ответ vfilby, вы можете просто выполнить замену RegEx в своем коде; новые классы не нужны. В случае, если другие новички, как я, наткнуться на этот вопрос.

using System.Text.RegularExpressions;

Тогда ...

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;
}
6 голосов
/ 11 октября 2017

Три шага для преобразования HTML в обычный текст

Сначала необходимо установить пакет Nuget для HtmlAgilityPack Второй Создать этот класс

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

Используя приведенный выше класс со ссылкой на ответ Джуды Химанго

В-третьих, вам нужно создать объект вышеупомянутого класса и использовать ConvertHtml(HTMLContent) Метод для преобразования HTML в обычный текст, а не ConvertToPlainText(string html);

HtmlToText htt=new HtmlToText();
var plainText = htt.ConvertHtml(HTMLContent);
4 голосов
/ 19 апреля 2017

Самый простой способ, который я нашел:

HtmlFilter.ConvertToPlainText(html);

Класс HtmlFilter находится в Microsoft.TeamFoundation.WorkItemTracking.Controls.dll

DLL можно найти в папке, подобной этой: % ProgramFiles% \ Common Files \ microsoft shared \ Team Foundation Server \ 14.0 \

В VS 2015, DLL также требует ссылки на Microsoft.TeamFoundation.WorkItemTracking.Common.dll, расположенный в той же папке.

4 голосов
/ 16 мая 2018

У него есть ограничение, заключающееся в том, что он не разрушает длинные встроенные пробелы, но он определенно переносим и соответствует макету как веб-браузер.

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 голосов
/ 26 марта 2013

Нет метода с именем 'ConvertToPlainText' в HtmlAgilityPack, но вы можете преобразовать строку html в строку CLEAR с помощью:

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

Это работает для меня. Но я не нашел метод с именем ConvertToPlainText в HtmlAgilityPack.

3 голосов
/ 09 мая 2012

Я думаю, что самый простой способ - создать метод расширения 'string' (основываясь на том, что предложил Ричард):

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

Затем просто используйте этот метод расширения для любой переменной 'string' в вашей программе:

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

Я использую этот метод расширения, чтобы преобразовать комментарии в формате html в обычный текст, чтобы он правильно отображался в отчете Crystal Reports и отлично работал!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...