2009-08-06 6 views
1

Ich habe einen HTML-Inhalt, der vom Benutzer über einen Richtext-Editor eingegeben wird, so dass es fast alles sein kann (weniger als außerhalb des Body-Tags, keine Sorgen über "Kopf" oder Doctype usw.). Ein Beispiel für diesen Inhalt:Extrahieren von Textfragmenten aus einem HTML-Body (in. NET)

<h1>Header 1</h1> 
<p>Some text here</p><p>Some more text here</p> 
<div align=right><a href="x">A link here</a></div><hr /> 
<h1>Header 2</h1> 
<p>Some text here</p><p>Some more text here</p> 
<div align=right><a href="x">A link here</a></div><hr /> 

Der Trick ist, ich brauche nur erste 100 Zeichen des Textes zu extrahieren (HTML-Tags entfernt). Ich muss auch die Zeilenumbrüche beibehalten und kein Wort brechen.

wird also der Ausgang für die oben so etwas wie:

Header 1 
Some text here 

Some more text here 

A link here 

Header 2 
Some text here 

Some 

Es hat 98 Zeichen und Zeilenumbrüche beibehalten werden. Was kann ich bisher erreichen ist, die alle HTML-Tags mit Regex abzustreifen:

Regex.Replace(htmlStr, "<[^>]*>", "") 

dann auch die Länge mit Regex trimmen mit:

Regex.Match(textStr, @"^.{1,100}\b").Value 

Mein Problem ist, wie man den Zeilenumbruch Halte ?. Ich erhalte eine Ausgabe wie:

Header 1 
Some text hereSome more text here 
A link here 
Header 2 
Some text hereSome more text 

Hinweis die Verbindungssätze? Vielleicht kann mir jemand andere Wege zeigen, dieses Problem zu lösen. Vielen Dank!

Zusätzliche Informationen: Mein Ziel ist es, aus einem Haufen HTML-Inhalt eine Klartext-Zusammenfassung zu generieren. Schätze dies wird helfen, das Problem zu klären.

+0

Versuchen Sie, einen sehr einfachen Browser zu erstellen? Ich frage, denn wenn es so ist, wird die Verwendung von Regex (offensichtlich) Sie nur so weit bringen. – phairoh

+0

@Phairoh Kein Browser, sondern eher ein automatischer Synopsengenerator. –

Antwort

0

Nun, ich muss das schließen, obwohl ich nicht die ideale Lösung habe. Da die in meiner App verwendeten HTML-Tags sehr gebräuchlich sind (keine Tabellen, Listen usw.) und nur wenig oder gar keine Verschachtelungen vorhanden sind, habe ich die HTML-Fragmente vorformatiert, bevor ich sie nach der Benutzereingabe abspeicherte.

  • Entfernen Sie alle Zeilenumbrüche
  • einen Zeilenumbruch Präfix für alle Block-Tags hinzufügen (zB div, p, h, h1/2/3/4 usw.)

Bevor ich sie extrahieren Um als Klartext angezeigt zu werden, verwenden Sie Regex, um das HTML-Tag zu entfernen und den Zeilenumbruch beizubehalten. Kaum eine Raketenwissenschaft funktioniert aber für mich.

1

Für Info, stripping HTML mit einem Regex ist ... voller subtiler Probleme. Die HTML Agility Pack kann robuster sein, aber leidet immer noch unter den Worten zusammen Blutungen:

konnte
HtmlDocument doc = new HtmlDocument(); 
doc.LoadHtml(html); 
string text = doc.DocumentNode.InnerText; 
+0

Ich habe Agility Pack ausprobiert. Ich mache mir keine Sorgen über das Entfernen der HTML-Tags, da Inhalt und Layout nicht allzu ausgefallen sind. Wie du gesagt hast, bluten die Worte immer noch zusammen. –

0

Eine Möglichkeit, html in drei Schritten strippen sein:

Regex.Replace(htmlStr, "<[^/>]*>", "") // don't strip </.*> 
Regex.Replace(htmlStr, "</p>", "\r\n") // all paragraph ends are replaced w/ new line 
Regex.Replace(htmlStr, "<[^>]*>", "") // replace remaining </.*> 
+0

Wenn das Absatz-Tag einen Zeilenumbruch hat, muss ich sicherstellen, dass keine zusätzliche Pause eingefügt wird. Ich muss auch aufpassen oder irgendwelche Blockelemente wie DIV und HR usw. Die Liste geht weiter und weiter. –

2

Ich denke, wie ich dieses Problem lösen soll sieh es dir an, als wäre es ein einfacher Browser. Erstellen Sie eine Basis-Tag-Klasse, machen Sie sie abstrakt mit einer InnerHTML-Eigenschaft und einer virtuellen Methode PrintElement.

Erstellen Sie als Nächstes Klassen für jedes HTML-Tag, das Sie interessieren und von Ihrer Basisklasse erben. Wenn Sie von Ihrem Beispiel ausgehen, sind die Tags, die Ihnen am meisten am Herzen liegen, h1, p, a und hr. Implementieren Sie die PrintElement-Methode so, dass sie eine Zeichenfolge zurückgibt, die das Element basierend auf InnerHTML korrekt ausgibt (z. B. würde die p-Klasse 'PrintElement "\ n [InnerHTML] \ n" zurückgeben). Erstellen Sie als Nächstes einen Parser, der durch Ihren HTML-Code analysiert und bestimmt, welches Objekt erstellt werden soll, und fügen Sie diese Objekte dann zu einer Warteschlange hinzu (ein Baum wäre besser, sieht aber nicht so aus, als wäre er für Ihre Zwecke erforderlich).

Schließlich durchlaufen Sie Ihre Warteschlange, indem Sie für jedes Element die PrintElement-Methode aufrufen.

Vielleicht mehr Arbeit, als Sie geplant hatten, aber es ist eine weitaus robustere Lösung als einfach Regex zu verwenden. Sollten Sie sich dazu entscheiden, Ihre Meinung in Zukunft zu ändern, möchten Sie nur ein einfaches Styling zeigen Ihre PrintElement-Methoden.

+0

Das ist wahrscheinlich eine bessere Lösung - wenn Sie p- und div-Tags so behandeln, wie sie sein sollten (Elemente auf Blockebene), sollte das Ersetzen durch neue Zeilen ganz gut funktionieren. –

+0

Wow, definitiv viel mehr Arbeit als ich zugeteilt hätte. Wie bereits erwähnt, ist es mein ultimativer Zweck, die oberste X-Zahl von Zeichen zu extrahieren und als einfachen Text anzuzeigen, ohne ein Wort zu brechen und den entsprechenden Zeilenumbruch zu erhalten, wie der HTML-Inhalt im Browser gerendert worden wäre. Aber danke, Pharioh, dass du etwas mitgebracht hast, an das ich nicht gedacht hätte. +1:) –