Come si converte l'Html in testo normale?


98

Ho frammenti di Html memorizzati in una tabella. Non intere pagine, nessun tag o simili, solo formattazione di base.

Vorrei essere in grado di visualizzare quell'Html solo come testo, senza formattazione , su una determinata pagina (in realtà solo i primi 30-50 caratteri, ma questa è la parte facile).

Come inserisco il "testo" all'interno di quell'Html in una stringa come testo semplice?

Quindi questo pezzo di codice.

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

Diventa:

Ciao mondo. C'è qualcuno là fuori?


Potresti voler usare SgmlReader. code.msdn.microsoft.com/SgmlReader
Leonardo Herrera

C'è del codice piuttosto semplice e diretto per convertire l'HTML in testo normale su blackbeltcoder.com/Articles/strings/convert-html-to-text .
Jonathan Wood

Questa era la risposta giusta per quello di cui avevo bisogno - grazie!
Shaul Behr

Ci sono alcuni buoni suggerimenti dal W3C qui: w3.org/Tools/html2things.html
Rich

4
In che modo una domanda può essere contrassegnata come un duplicato di una domanda posta 6 mesi dopo? Sembra un po 'arretrato ...
Stuart Helwig,

Risposte:


28

Se stai parlando di tag stripping, è relativamente semplice se non devi preoccuparti di cose come i <script>tag. Se tutto ciò che devi fare è visualizzare il testo senza i tag, puoi farlo con un'espressione regolare:

<[^>]*>

Se devi preoccuparti dei <script>tag e simili, allora avrai bisogno di qualcosa di un po 'più potente delle espressioni regolari perché devi tenere traccia dello stato, qualcosa di più simile a una Context Free Grammar (CFG). Anche se potresti essere in grado di farlo con la corrispondenza "Da sinistra a destra" o non avida.

Se puoi usare le espressioni regolari ci sono molte pagine web là fuori con buone informazioni:

Se hai bisogno del comportamento più complesso di un CFG ti suggerirei di utilizzare uno strumento di terze parti, purtroppo non ne conosco uno buono da consigliare.


3
Devi anche preoccuparti di> nei valori degli attributi, commenti, PI / CDATA in XML e vari tipi di malformazioni comuni nell'HTML legacy. In generale [X] [HT] ML non è suscettibile di analisi con espressioni regolari.
bobince

11
Questo è un metodo terribile per farlo. Il modo corretto è analizzare l'HTML con una lib e attraversare il dom restituendo solo il contenuto nella whitelist.
usr

2
@usr: la parte a cui ti riferisci è la parte CFG della risposta. Regex può essere utilizzato per rimuovere tag in modo rapido e sporco, ha i suoi punti deboli ma è veloce ed è facile. Per un'analisi più complicata usa uno strumento basato su CFG (nel tuo gergo una libreria che genera un DOM). Non ho eseguito i test, ma scommetterei che l'analisi DOM è più lenta dello stripping delle regex, nel caso in cui le prestazioni debbano essere considerate.
vfilby

1
@vfilby, il primo attacco che mi viene in mente è scrivere "<div id = \" "(sintassi della stringa c #). Nota le virgolette finali mancanti e le parentesi graffe mancanti. Immagino che questo confonderà il browser e sbilancerà la struttura del tag. pensi a questo attacco? Puoi essere sicuro che non funzioni mai? Nasty.
usr

1
@vfilby, non importa se la libreria di analisi è confusa o meno. Tutto quello che devi fare è prendere il DOM da esso (qualsiasi DOM) e visualizzare solo i componenti nella whitelist. Questo è sempre sicuro, non importa come appare il DOM analizzato. Inoltre, ti ho detto diversi esempi in cui il tuo metodo "semplice" non riuscirà a rimuovere i tag.
usr

95

L' HtmlAgilityPack gratuito e open source ha in uno dei suoi esempi un metodo che converte da HTML a testo normale.

var plainText = HtmlUtilities.ConvertToPlainText(string html);

Alimentalo con una stringa HTML come

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

E otterrai un risultato di testo semplice come:

hello world!

10
Ho già utilizzato HtmlAgilityPack ma non riesco a vedere alcun riferimento a ConvertToPlainText. Sei in grado di dirmi dove posso trovarlo?
horatio

8
Horatio, è incluso in uno degli esempi forniti con HtmlAgilityPack: htmlagilitypack.codeplex.com/sourcecontrol/changeset/view/…
Judah Gabriel Himango

5
In realtà, non esiste un metodo integrato per questo nell'Agility Pack. Che cosa si è collegato al è un esempio che utilizza il pacchetto Agility per attraversare il nodo della struttura, rimuovere scripte styletag e scrivere il testo interno di altri elementi nella stringa di output. Dubito che abbia superato molti test con input del mondo reale.
Lou

3
Qualcuno può fornire un codice che funzioni, invece di collegamenti a campioni che devono essere adattati per funzionare correttamente?
Eric K

5
L'esempio può ora essere trovato qui: github.com/ceee/ReadSharp/blob/master/ReadSharp/…
StuartQ

51

Non potevo usare HtmlAgilityPack, quindi ho scritto una seconda migliore soluzione per me stesso

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; è stato analizzato così ho spostato il testo = System.Net.WebUtility.HtmlDecode (text); alla fine del metodo
Luuk

1
È stato fantastico, ho anche aggiunto un condensatore multispazio poiché l'html potrebbe essere stato generato da un CMS: var spaceRegex = new Regex ("[] {2,}", RegexOptions.None);
Enkode

A volte, nel codice html c'è la nuova riga del programmatore (la nuova riga non può essere vista nei commenti, quindi la mostro con [nuova riga], come: <br> I [nuova riga] manca [nuova riga] tu <br >, Quindi si suppone che mostri: "Mi manchi", ma mostra che mi manchi [nuova riga] [nuova riga]. Questo fa sembrare doloroso il testo normale. Sai come risolvere?
123iamking

@ 123iamking puoi usarlo prima di restituire il testo; : text.Replace ("[nuova riga]", "\ n");
Eslam Badawy

Lo stavo usando e mi sono reso conto che a volte lascia ">" all'inizio delle stringhe. L'altra soluzione per applicare la regex <[^>] *> funziona bene.
Etienne Charland

20

HTTPUtility.HTMLEncode()ha lo scopo di gestire la codifica dei tag HTML come stringhe. Si prende cura di tutti i lavori pesanti per te. Dalla documentazione di MSDN :

Se caratteri come spazi e punteggiatura vengono passati in un flusso HTTP, potrebbero essere interpretati erroneamente all'estremità ricevente. La codifica HTML converte i caratteri non consentiti in HTML in equivalenti di entità carattere; La decodifica HTML inverte la codifica. Ad esempio, quando sono incorporati in un blocco di testo, i caratteri <e >, sono codificati come &lt;e &gt;per la trasmissione HTTP.

HTTPUtility.HTMLEncode()metodo, dettagliato qui :

public static void HtmlEncode(
  string s,
  TextWriter output
)

Utilizzo:

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

Una risposta davvero buona George, grazie, ha anche evidenziato quanto male ho posto la domanda la prima volta. Scusate.
Stuart Helwig

html agility pack è
obsoleto

10

Per aggiungere alla risposta di vfilby, puoi semplicemente eseguire una sostituzione RegEx all'interno del tuo codice; non sono necessarie nuove classi. Nel caso in cui altri neofiti come me inciamperanno su questa domanda.

using System.Text.RegularExpressions;

Poi...

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
NON BENE! Questo può essere ingannato per contenere lo script omettendo la parentesi angolare di chiusura. RAGAZZI, non inserite mai nella lista nera. Non è possibile disinfettare l'input inserendolo nella lista nera. Questo è così sbagliato.
usr

7

Processo in tre fasi per convertire HTML in testo normale

Per prima cosa devi installare il pacchetto Nuget per HtmlAgilityPack. Secondo creare questa classe

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

Usando la classe sopra con riferimento alla risposta di Judah Himango

Terzo, è necessario creare l'oggetto della classe precedente e utilizzare il ConvertHtml(HTMLContent)metodo per convertire l'HTML in testo normale anzichéConvertToPlainText(string html);

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

posso saltare la conversione dei link in html. devo mantenere i collegamenti in html durante la conversione in testo?
coder771

6

Ha una limitazione che non fa collassare lunghi spazi bianchi in linea, ma è sicuramente portatile e rispetta il layout come il browser 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

Non esiste un metodo con il nome 'ConvertToPlainText' in HtmlAgilityPack ma puoi convertire una stringa html in una stringa CLEAR con:

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

Questo funziona per me. MA NON TROVO UN METODO CON IL NOME "ConvertToPlainText" IN "HtmlAgilityPack".


3

Penso che il modo più semplice sia creare un metodo di estensione 'stringa' (basato su ciò che l'utente Richard ha suggerito):

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

Quindi usa questo metodo di estensione su qualsiasi variabile 'stringa' nel tuo programma:

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

Uso questo metodo di estensione per convertire i commenti formattati html in testo normale in modo che venga visualizzato correttamente su un report di cristallo e funziona perfettamente!


3

Il modo più semplice che ho trovato:

HtmlFilter.ConvertToPlainText(html);

La classe HtmlFilter si trova in Microsoft.TeamFoundation.WorkItemTracking.Controls.dll

La dll può essere trovata in una cartella come questa:% ProgramFiles% \ Common Files \ microsoft shared \ Team Foundation Server \ 14.0 \

In VS 2015, la dll richiede anche il riferimento a Microsoft.TeamFoundation.WorkItemTracking.Common.dll, che si trova nella stessa cartella.


si prende cura dei tag di script e si formatta in grassetto corsivo ecc.?
Samra

Presentazione di una dipendenza dalla base del team per la conversione di HTML in testo normale, molto discutibile ...
ViRuSTriNiTy

2

Se si dispone di dati con tag HTML e si desidera visualizzarli in modo che una persona possa VEDERE i tag, utilizzare HttpServerUtility :: HtmlEncode.

Se si dispone di dati che contengono tag HTML e si desidera che l'utente veda i tag renderizzati, visualizzare il testo così com'è. Se il testo rappresenta un'intera pagina web, utilizza un IFRAME.

Se disponi di dati con tag HTML e desideri rimuovere i tag e visualizzare solo il testo non formattato, utilizza un'espressione regolare.


in php c'è una funzione chiamata striptags () forse hai qualcosa di simile
markus

"usa un'espressione regolare" NO! Questa sarebbe la lista nera. Puoi essere sicuro solo facendo la whitelist. Ad esempio, ti sei ricordato che l'attributo style può contenere "background: url ('javascript: ...');"? certo che no, non l'avrei nemmeno io. Ecco perché la lista nera non funziona.
usr

2

Ho affrontato un problema simile e ho trovato la soluzione migliore. Di seguito il codice funziona perfettamente per me.

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

}

I caratteri di escape come \ ne \ r dovevano essere prima rimossi perché causano il mancato funzionamento delle espressioni regolari come previsto.

Inoltre, per fare in modo che la stringa del risultato venga visualizzata correttamente nella casella di testo, potrebbe essere necessario dividerla e impostare la proprietà Lines della casella di testo invece di assegnarla alla proprietà Text.

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

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


0

Dipende da cosa intendi per "html". Il caso più complesso sarebbe pagine web complete. Questo è anche il più facile da gestire, poiché puoi utilizzare un browser web in modalità testo. Consulta l' articolo di Wikipedia che elenca i browser web, inclusi i browser in modalità testo. La lince è probabilmente la più conosciuta, ma una delle altre potrebbe essere migliore per le tue esigenze.


come ha detto "Ho frammenti di HTML memorizzati in una tabella."
M al

0

Ecco la mia soluzione:

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

Esempio:

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

0

Avevo la stessa domanda, solo il mio html aveva un semplice layout pre-noto, come:

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

Quindi ho finito per usare un codice così semplice:

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

Quali uscite:

abc
def

0

Non ha scritto ma utilizzando:

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

Penso che abbia una risposta semplice:

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

0

Per chiunque cerchi una soluzione esatta alla domanda OP per un'abbreviazione testuale di un dato documento html, senza newline e tag HTML, trova la soluzione di seguito.

Come per ogni soluzione proposta, ci sono alcune ipotesi con il codice seguente:

  • i tag di script o di stile non devono contenere tag di script e di stile come parte dello script
  • solo gli elementi inline principali saranno inline senza spazio, cioè he<span>ll</span>odovrebbero essere visualizzati hello. Elenco dei tag in linea: https://www.w3schools.com/htmL/html_blocks.asp

Considerando quanto sopra, la seguente estensione di stringa con espressioni regolari compilate produrrà un testo normale previsto per quanto riguarda i caratteri html con escape e null su input 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 (">", ">"); }

In questo modo esegui l'escape di tutti i "<" e ">" in una stringa. È questo che vuoi?


... ah. Bene, ora la risposta (insieme all'interpretazione della domanda ambigua) è completamente cambiata, prenderò le lendini per la mancanza di & amp; codifica invece. ;-)
bobince

2
Non credo sia una buona idea reinventare la ruota, specialmente quando la tua ruota è quadrata. Dovresti invece usare HTMLEncode.
Kramii
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.