2013-04-14 8 views
5

Mit Regex möchte ich den Text zwischen mehreren DIV-Tags erhalten können. Zum Beispiel die folgende:Verwenden von Regex, um Text zwischen mehreren HTML-Tags zu erhalten

<div>first html tag</div> 
<div>another tag</div> 

ausgeben würde:

first html tag 
another tag 

Das RegexMuster ich verwende nur passt meine letzte Div-Tag und verfehlt das erste. Code:

static void Main(string[] args) 
    { 
     string input = "<div>This is a test</div><div class=\"something\">This is ANOTHER test</div>"; 
     string pattern = "(<div.*>)(.*)(<\\/div>)"; 

     MatchCollection matches = Regex.Matches(input, pattern); 
     Console.WriteLine("Matches found: {0}", matches.Count); 

     if (matches.Count > 0) 
      foreach (Match m in matches) 
       Console.WriteLine("Inner DIV: {0}", m.Groups[2]); 

     Console.ReadLine(); 
    } 

Ausgang:

Objekte gefunden: 1

Inner DIV: Dies ist ein weiterer Test

+1

ist es unerlässlich, diese Aufgabe, die Sie Verwenden Sie einen regulären Ausdruck? HTML ist eine kontextfreie Grammatik, die nicht mit regulären Ausdrücken geparst werden kann. Oftmals können Sie sich nähern, aber es wäre besser, einen HTML-Parser zu verwenden. Siehe http://StackOverflow.com/a/1732454/2022565 –

Antwort

9

Ersetzen Sie Ihre Muster mit einem nicht gierig Spiel

static void Main(string[] args) 
{ 
    string input = "<div>This is a test</div><div class=\"something\">This is ANOTHER test</div>"; 
    string pattern = "<div.*?>(.*?)<\\/div>"; 

    MatchCollection matches = Regex.Matches(input, pattern); 
    Console.WriteLine("Matches found: {0}", matches.Count); 

    if (matches.Count > 0) 
     foreach (Match m in matches) 
      Console.WriteLine("Inner DIV: {0}", m.Groups[1]); 

    Console.ReadLine(); 
} 
+0

Es fand beide Übereinstimmungen, aber zeigt leere Werte in meinem Programm – ben

+0

Der obige Code sollte funktionieren, beachten Sie, dass seine m.Groups [1] und nicht m .Groups [2], da ich es ein wenig geändert habe, da es keinen Grund gibt, das Tag selbst zu erfassen. http://www.rubular.com/r/XQrcobmfAK – coolmine

1

Zuerst einmal erinnern • dass Sie in der HTML-Datei ein neues Zeilensymbol ("\ n") haben, das Sie nicht in den String aufgenommen haben, mit dem Sie Ihre Regex überprüfen.

Zweite von Ihnen nehmen regex:

((<div.*>)(.*)(<\\/div>))+ //This Regex will look for any amount of div tags, but it must see at least one div tag. 

((<div.*>)(.*)(<\\/div>))* //This regex will look for any amount of div tags, and it will not complain if there are no results at all. 

auch ein guter Ort für diese Art von Informationen zu suchen:

http://www.regular-expressions.info/reference.html

http://www.regular-expressions.info/refadv.html

Mayman

0

Die kurze Version ist das du kann das nicht in allen Situationen richtig machen. Es wird immer Fälle von gültigem HTML geben, für die ein regulärer Ausdruck die gewünschten Informationen nicht extrahieren kann.

Der Grund ist, weil HTML eine kontextfreie Grammatik ist, die eine komplexere Klasse als ein regulärer Ausdruck ist.

Hier ist ein Beispiel - was ist, wenn Sie mehrere gestapelte Divs haben?

<div><div>stuff</div><div>stuff2</div></div> 

Die regulären Ausdrücke wie andere Antworten aufgelistet werden greifen:

<div><div>stuff</div> 
<div>stuff</div> 
<div>stuff</div><div>stuff2</div> 
<div>stuff</div><div>stuff2</div></div> 
<div>stuff2</div> 
<div>stuff2</div></div> 

, weil das ist, was reguläre Ausdrücke tun, wenn sie versuchen, HTML zu analysieren.

Sie können keinen regulären Ausdruck schreiben, der die Interpretation aller Fälle versteht, da reguläre Ausdrücke dazu nicht in der Lage sind. Wenn Sie mit einem sehr spezifischen eingeschränkten HTML-Satz arbeiten, ist dies möglicherweise möglich, aber Sie sollten diese Tatsache im Hinterkopf behalten.

Weitere Informationen: https://stackoverflow.com/a/1732454/2022565

1

Haben Sie am Html Agility Pack sehen (siehe https://stackoverflow.com/a/857926/618649)?

CsQuery sieht auch ziemlich nützlich (im Grunde verwenden CSS-Selektor-Stil-Syntax, um die Elemente zu erhalten). Siehe https://stackoverflow.com/a/11090816/618649.

CsQuery ist im Grunde genommen "jQuery for C#", was ziemlich genau die Suchkriterien sind, die ich verwendet habe, um es zu finden.

Wenn Sie dies in einem Webbrowser tun könnten, könnten Sie problemlos jQuery verwenden, indem Sie eine ähnliche Syntax wie $("div").each(function(idx){ alert(idx + ": " + $(this).text()); } verwenden (nur Sie würden das Ergebnis natürlich in das Protokoll oder den Bildschirm ausgeben oder einen Web-Service-Aufruf damit machen), oder was immer du damit machen musst).

+0

Ein Downvote ohne Erklärung oder Kommentar. Vielen Dank! Tatsache ist, dass HTML/XML notorisch ein Schmerz im Nacken ist, um mit Regex umzugehen. Nicht, dass Sie es nicht tun können, und ich habe sicherlich bei zahlreichen Gelegenheiten, aber CSS-Selektor-Syntax ist ein viel saubereres Angebot. – Craig

1

ich diesen Code denken sollte funktionieren:

string htmlSource = "<div>first html tag</div><div>another tag</div>"; 
string pattern = @"<div[^>]*?>(.*?)</div>"; 
MatchCollection matches = Regex.Matches(htmlSource, pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline); 
ArrayList l = new ArrayList(); 
foreach (Match match in matches) 
{ 
    l.Add(match.Groups[1].Value); 
} 
7

Wie andere Jungs nicht HTML tags with attributes erwähnt haben, hier ist meine Lösung damit umgehen:

// <TAG(.*?)>(.*?)</TAG> 
// Example 
var regex = new System.Text.RegularExpressions.Regex("<h1(.*?)>(.*?)</h1>"); 
var m = regex.Match("Hello <h1 style='color: red;'>World</h1> !!"); 
Console.Write(m.Groups[2].Value); // will print -> World 
Verwandte Themen