2012-09-19 11 views
7

Ich habe die folgende Zeichenfolge:Regex Text ersetzen, aber ausschließen, wenn der Text zwischen bestimmtem Tag ist

Lorem ipsum Test dolor sit amet, consetetur sadipscing elitr, sed diam nonumy <a href="http://Test.com/url">Test</a> eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd sed Test dolores et ea rebum. Stet clita kasd gubergren, no sea <a href="http://url.com">Test xyz</a> takimata sanctus est Lorem ipsum dolor sit amet. 

Jetzt würde ich die Zeichenfolge ‚Test‘ außerhalb von Tags ersetzt eine nicht zwischen den Tags (zB ersetzt mit ‚1234‘).

Lorem ipsum 1234 dolor sit amet, consetetur sadipscing elitr, sed diam nonumy <a href="http://Test.com/url">Test</a> eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd sed 1234 dolores et ea rebum. Stet clita kasd gubergren, no sea <a href="http://url.com">Test xyz</a> takimata sanctus est Lorem ipsum dolor sit amet. 

Ich begann mit diesem Regex: (?!<a[^>]*>)(Test)([^<])(?!</a>)

aber zwei Probleme sind nicht gelöst:

  1. Der Text 'Test' wird auch innerhalb von Tags ersetzt (zB)
  2. den Text Does zwischen dem Tag stimmt der gesuchte Text nicht genau überein, es wird auch ersetzt (zB <a href="http://url">Test xyz</a>)

Ich hoffe, jemand hat eine Lösung, um dieses Problem zu lösen.

Antwort

9
(?!<a[^>]*?>)(Test)(?![^<]*?</a>) 

gleiche wie zb226, aber mit einem faulen Spiel optimiert

Auch reguläre Ausdrücke verwenden auf rohen HTML nicht empfohlen.

+0

ich die \ b Flagge auch eine Wortgrenze entsprechen ändern hinzugefügt (?! [^ <]*?) – Weri

+0

Das sollte den Regex-Optimierer mehr zum Arbeiten geben. Es sollte auch keine negativen Auswirkungen auf Ihre Übereinstimmungen haben, solange '_Test_, _Test oder Test_' nicht in Ihrem Dokument enthalten sind (und vorausgesetzt, Sie würden nicht darauf achten, sie zu vergleichen, wenn sie es wären). – protist

+0

Die Lookaheed vor Test und das faule Match sind bedeutungslos. Siehe meine Antwort. – Adam

3

Diese den Trick tun sollten:

(?!<a[^>]*>)(Test)(?![^<]*</a>) 

Probieren Sie es selbst on regexr.

2

Diese uralte Frage auferstehen, weil es eine einfache Lösung hatte, die nicht erwähnt wurde.

Mit all den Disclaimern über die Verwendung von Regex zum Parsen von HTML, hier ist eine einfache Möglichkeit, es zu tun.

Methode für Perl/PCRE

<a[^>]*>[^<]*<\/a(*SKIP)(*F)|Test 

demo

Allgemeine Lösung

<a[^>]*>[^<]*<\/a|(Test) 

In dieser Version wird der Text ersetzt werden soll, wird in der Gruppe 1 eingefangen und die Ersatz wird durch einen einfachen Callback oder Lambda durchgeführt.

demo

Referenz

  1. How to match pattern except in situations s1, s2, s3
  2. Für Code-Implementierung finden Sie in die Code-Beispiele in How to match a pattern unless...
+0

Der wichtigste Teil war für mich zu wissen, '$ ersetzt = preg_replace_callback ( \t $ regex, \t Funktion ($ m) {if (empty ($ m [1])) return $ m [0]; \t \t \t \t \t sonst Rückgabe "Superman";}, \t $ Betreff); '. Also muss ich 'm [0]' zurückgeben, wenn 'm [1]' leer ist. Wirklich nett zu wissen. Vielen Dank! – mgutt

4

es sinnlos ist, einen Look-Ahead vor dem Spiel zu setzen.So nach dem entspricht Protisten Antwort:

(Test)(?![^<]*?</a>) 

auch da < nicht das faule Spiel erlaubt ? überflüssig ist, so dass sie auch gleich

(Test)(?![^<]*</a>) 

Dies wählt all Test, die nicht gefolgt werden von eine </a> ohne das Symbol < dazwischen. Deshalb wird Test, der vor oder nach <a ...> .. </a> erscheint, ersetzt.

Beachten Sie jedoch, dass

Lorem Test dolor <a href="http://Test.com/url">Test <strong>dolor</strong></a> eirmod 

würde

Lorem 1234 dolor <a href="http://1234.com/url">1234 <strong>dolor</strong></a> eirmod 

Um geändert werden, um zu fangen, dass Sie Ihre Regex

(Test)(?!(.(?!<a))*?</a>) 

ändern könnte, was geschieht Folgendes:

Wählen Sie jedes Wort Test aus, auf das keine Zeichenfolge ***</a> folgt, wobei auf jedes Zeichen in *** nicht <a folgt.

Beachten Sie, dass hier die faule Übereinstimmung ? sinnvoll ist.

Protisten sagte

Auch reguläre Ausdrücke auf rohe HTML wird nicht empfohlen.

Ich stimme dem zu. Ein Problem ist, dass es Probleme verursachen würde, wenn ein Tag nicht geschlossen oder offen ist. (?!? ] *>) (\ btest \ b): Zum Beispiel alle hier genannten Lösungen würden

Lorem Test dolor Test <strong>dolor</strong></a> eirmod 

zu

Lorem Test dolor Test <strong>dolor</strong></a> eirmod 1234 dolores sea 1234 takimata 
Verwandte Themen