2009-06-05 8 views
16

Ich habe einige Schwierigkeiten mit einem bestimmten Regex Ich versuche zu verwenden. Ich suche nach jedem Vorkommen eines Strings (für meine Zwecke werde ich sagen, dass es "mystring" ist) in einem Dokument, außer wo es in einem Tag ist, z. Regex verwenden, um bestimmte Zeichenfolge nicht in HTML-Tag zu finden

<a href="_mystring_"> 

sollte nicht überein, aber

<a href="someotherstring">_mystring_</a> 

Sollte übereinstimmen, da es nicht in einem Tag ist (im Sinne von „im Inneren des < und> Marker“) Ich habe für diese .NET regex Funktionen bin mit auch.

+0

meinst du Ihr zweites Beispiel sollte * nicht * übereinstimmen? –

+5

[Bitte schreiben Sie nicht "regexes verwenden, um HTML zu analysieren" antworten Sie hier] –

+1

robbotic: nein, es sollte übereinstimmen. Es ist nicht innerhalb der < and > Marker. Ich muss eine Ersetzung auf _mystring_ vornehmen, aber nicht, wenn es Teil des Tags ist, wie es im oberen Beispiel ist. Auch das Laden dieses in ein XDocument oder was auch immer ist in meiner Situation nicht wirklich machbar. – Sukasa

Antwort

17

Dies sollte es tun:

(?<!<[^>]*)_mystring_ 

Es verwendet einen negativen Blick hinter zu prüfen, ob der gefundene String keine <, bevor es hat, ohne ein entsprechendes>

+0

Obwohl Ich brauchte ein paar Regeln mehr für den Lookbehind und so für meine spezifischen Bedürfnisse, das ist es, was die Dinge für mich funktioniert. Vielen Dank! – Sukasa

+1

Wow, das ist eine wunderschöne Regex! @Sukasa, kannst du den letzten Beitrag posten, den du erfunden hast? – travis

+1

Funktioniert nicht mit PHP obwohl –

0

Warum Regex verwenden?

Für xhtml, laden Sie es in XDocument/XmlDocument; für (nicht-x) html scheint das Html Agility Pack eine vernünftigere Wahl zu sein ...

Wie auch immer, das wird die HTML in ein DOM parsen, so dass Sie über die Knoten iterieren und sie überprüfen können.

0

Suchen mit regulärem Ausdruck ist normalerweise keine gute Idee in XML. Es ist zu einfach, Probleme mit zu viel oder zu wenig passenden Suchausdrücken zu bekommen. Es ist auch fast unmöglich, eine Regex zu formulieren, die CDATA-Abschnitte, Verarbeitungsanweisungen (PIs) und Escape-Sequenzen, die XML zulässt, korrekt identifizieren und verarbeiten kann.

Es sei denn, Sie haben die vollständige Kontrolle über den XML-Inhalt, den Sie erhalten, und können sicherstellen, dass sie solche Konstrukte nicht enthält (und sich nicht ändert). Ich würde empfehlen, einen XML-Parser irgendeiner Art (XDocument oder XmlDocument in) zu verwenden .net, zum Beispiel).

Mit dem gesagt, wenn Sie immer noch beabsichtigen, Regex als Suchmechanismus zu verwenden, sollte etwas wie das Folgende funktionieren, die RegEx-Klasse in .NET verwenden. Möglicherweise möchten Sie test it out mit einigen Ihrer eigenen Testfälle auf einer Website wie Regexlib. Möglicherweise können Sie auch ihren regulären Ausdruckskatalog durchsuchen, um etwas zu finden, das Ihren Anforderungen entspricht.

[>]. (_mystring_). [<]

0

ignorierend, dass es in der Tat andere Wege, und dass ich keine wirkliche regex-Experte, aber eine Sache, die in meinem Kopf auftauchte war:

  • finden Sie alle mystring basta ARE in Tags zuerst -, weil ich nicht den Ausdruck schreiben kann das Gegenteil :)
  • Veränderung diejenigen etwas anderes
  • dann ersetzen alle anderen myString (die bleiben nicht in Tags) zu tun, wie Sie benötigen
  • die ursprüngliche mystring s wiederherstellen, also

in Tags waren, verwenden Sie die markierten diejenigen zu finden. Ersetzen Sie diese durch andereString. Normale ersetzen Sie auf der Mystring s, die übrig sind.Ersetzen andere zurück zu mystring

Crude aber effektiv .... vielleicht.

2

A quick and dirty Alternative ist, Verwenden Sie eine Regex-Replace-Funktion mit Callback, um den Inhalt von Tags zu codieren (alles zwischen < und>), zum Beispiel mit base64, führen Sie dann Ihre Suche aus und führen Sie einen weiteren Callback aus, um Ihre Tag-Inhalte zu dekodieren.

Dies kann auch eine Menge Kopf sparen Kratzen, wenn Sie bestimmte Tags von einer regex Suche ausschließen müssen - sie zuerst verschleiern und wickeln Sie sie in einem Marker, die Ihre Suche nicht übereinstimmen, dann führen Sie Ihre Suche, dann entblößt alles, was in Markern ist.

7

Wenn Ihr Regex Prozessor nicht mit variabler Länge Blick hinter nicht unterstützt, versuchen Sie dies:

(<.+?>[^<>]*?)(_mystring_)([^<>]*?<.+?>) 

Preserve Erfassen Sie die Gruppen 1 und 3 und ersetzen Sie die Erfassungsgruppe 2:

Zum Beispiel in Eclipse finden:

(<.+?>[^<>]*?)(_mystring_)([^<>]*?<.+?>) 

und ersetzen mit:

$1_newString_$3 

(Andere regex Prozessoren eine andere Capture-Gruppe Syntax verwenden könnte, wie \ 1)

+0

Dies ist die Antwort, die Sie in PHP verwenden müssen, fand ich ... schließlich. –

Verwandte Themen