2009-07-22 2 views
1

Wie finden Sie den Wert der Zeichenfolge, die wiederholt wird und die Daten zwischen ihnen mit Regexes? Nehmen Sie zum Beispiel dieses Stück XML:Wie finden Sie eine wiederholte Zeichenfolge und den Wert zwischen ihnen mit Regexes?

Was wäre die richtige Regex, um diese Werte zu finden? (Beachte, dass tagName irgendetwas sein kann).

Ich habe einen Weg gefunden, die funktioniert, die alle tagName s beinhaltet zu finden, die dazwischen eine Reihe von < > sind und dann für die erste Instanz des tagName aus dem Starttag bis zum Ende des Strings suchen und dann das Schließen der Suche nach </tagName> und die Daten zwischen ihnen ausarbeiten. Dies ist jedoch extrem ineffizient und komplex. Es muss einen leichteren Weg geben!

EDIT: Bitte sagen Sie mir nicht, XMLReader zu verwenden; Ich bezweifle, dass ich jemals meine benutzerdefinierte Klasse zum Lesen von XML verwenden werde. Ich versuche, den besten Weg (und die falschen Wege) zu lernen, indem ich versuche, mein eigenes zu erstellen.

Vielen Dank im Voraus.

+0

Nun stecken - das ist ein wenig snarky klingt, aber ich meine es nicht auf diese Weise - Sie sind definitiv auf dem richtigen Weg, um eine der falschen Wege zu lernen. Es gibt eine Rolle für reguläre Ausdrücke beim Erstellen eines XML-Readers, aber beim Scannen und nicht beim Parsen. –

+0

Ah, wahrscheinlich hast du recht. Ich habe es richtig gemacht, wenn Sie nur haben und so weiter, aber es fällt in Bits, wenn hinzugefügt wird oder etwas anderes und ich kann nicht sehen, wie es an die Arbeit anzupassen. –

Antwort

5

Sie verwenden können: <(\w+)>(.*?)<\/\1>

Gruppe # 1 ist der Tag, Gruppe # 2 ist der Inhalt .

+0

Danke, das ist wirklich nützlich. –

0

mit Perl:

my $tagName = 'some tag'; 
my $i; # some line of XML 
$i =~ /\<$tagName\>(.+)\<\/$tagname\>/; 

wo $ 1 jetzt mit den Daten, die Sie

erfaßt gefüllt ist
+0

Das wusste ich schon von Perl, und die Frage ist C#. –

+0

Entschuldigung C Rogers - Ich habe nicht alle Tags gelesen! – dls

2

Sie können eine Rückreferenzierung wie \1 verwenden zu einem früheren Spiel zu verweisen:

@"<([^>]*)>(.*)</\1>" 

Die \1 wird dem entsprechen, was von der ersten geklammerten Gruppe gefangen genommen wurde.

3

Die Verwendung von regulären Ausdrücken zum Parsen von XML ist ein schrecklicher Fehler.

Das ist effizient (sie analysieren nicht die XML in einen DOM) und einfach:

string s = "<tagName>Data between the tag</tagName>"; 

using (XmlReader xr = XmlReader.Create(new StringReader(s))) 
{ 
    xr.Read(); 
    Console.WriteLine(xr.ReadElementContentAsString()); 
} 

Edit:

Da das eigentliche Ziel ist hier etwas, von zu lernen, zu tun, und nicht nur zu bekommen den Job zu erledigen, ist hier, warum mit regulären Ausdrücken nicht funktioniert:

Betrachten Sie diese ziemlich trivial Testfall:

<a><b><a>text1<b>CDATA<![<a>text2</a>]]></b></a></b>text3</a> 

In diesem XML gibt es zwei Elemente mit einem Tag-Namen "a". Der erste hat einen Text-Knoten Kind mit einem Wert von "Text1", und der zweite hat einen Text-Knoten Kind mit einem Wert von "Text3". Außerdem gibt es ein "b" -Element, das eine Textzeichenfolge enthält, die wie ein "a" -Element aussieht, aber nicht, weil es in einem CDATA-Abschnitt eingeschlossen ist.

Sie können das nicht durch einfaches Pattern-Matching analysieren. Suche <a> und mit Blick auf die Suche nach </a> nicht beginnen zu tun, was Sie brauchen.Sie müssen Start-Tags auf einem Stapel platzieren, wenn Sie sie finden, und sie vom Stapel entfernen, wenn Sie das passende End-Tag erreichen. Sie müssen stoppen setzen Sie alles auf dem Stapel, wenn Sie den Beginn eines CDATA-Abschnitt auftreten, und nicht neu starten, bis Sie das Ende finden.

Und das ohne Whitespace, leere Elemente, Attribute, Verarbeitungsanweisungen, Kommentare oder Unicode in das Problem einzuführen.

+0

Ich versuche meinen eigenen "XMLReader" zu erstellen. Es wird nicht schnell/effizient/brauchbar sein oder jemals benutzt werden, aber ich denke, dass Leute versuchen sollten, Dinge von Grund auf aufzubauen, anstatt immer auf APIs zurückzugreifen, damit sie zumindest die Ideen dahinter kennen und warum der Code sie erstellt war so schlecht. Sind Sie wirklich ein Computerwissenschaftler, wenn Sie keine schnelle Multiplikation durchführen oder sogar eine Zeichenfolge umkehren können, ohne .NET/Java/was auch immer in der Bibliothek zu verwenden. Vielleicht nicht. Mit den Regex haben Sie vielleicht Recht. Trotzdem werde ich es versuchen, dann scheitern und dann lernen. –

+0

Ich glaube nicht, dass du jemanden dafür kennzeichnest, dass er auf den besten Weg hinweist, etwas zu erreichen, nur weil du es absichtlich auf die schwierige Art und Weise tun willst. –

+0

Zugegeben, ich hatte nur das Gefühl, dass ich meine Aktionen erklären musste, indem ich die schwierige/scheiternde Wurzel wählte. –

0

vorwärts gehen, wenn Sie regexlib.com Besuche stecken

Es ist der erste Ort, den ich gehen, wenn ich auf Regex

Verwandte Themen