2012-09-19 6 views
7

Mam następujący ciąg:Regex zamienić tekst jednak wykluczyć, gdy tekst jest między konkretnego tagu

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. 

Teraz chciałbym zastąpić ciąg poza „test” tagów nie między znacznikami (np zastąpione „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. 

zacząłem z tym regex: (?!<a[^>]*>)(Test)([^<])(?!</a>)

jednak dwa problemy nie zostały rozwiązane:

  1. tekst 'test' zostanie także zastąpione wewnątrz Tags (np)
  2. Czy tekst między tagiem nie jest dokładnie zgodny z wyszukiwanym tekstem, zostanie również zastąpiony (np. <a href="http://url">Test xyz</a>)

Mam nadzieję, że ktoś ma rozwiązanie, aby rozwiązać ten problem.

Odpowiedz

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

samo jak zb226, ale zoptymalizowany leniwe meczu

Ponadto, przy użyciu regexes na surowy HTML Niepolecane.

+0

Dodałem też flagę \ b pasujące granicę słowo: (?!? ] *>) (\ BTEST \ b) (?! [^ <]*?) – Weri

+0

To powinno dać optymalizatorowi regex więcej do pracy. Nie powinno to również wpływać negatywnie na twoje mecze, dopóki '_Test_, _Test lub Test_' nie znajdują się w Twoim dokumencie (i zakładasz, że nie będziesz chciał dopasować ich, jeśli były). – protist

+0

Lookaheaed przed Testem i leniwy mecz są bez znaczenia. Zobacz moją odpowiedź. – Adam

3

To powinno załatwić sprawę:

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

spróbować samemu on regexr.

2

Wskrzeszenie tego starożytnego pytania, ponieważ miało proste rozwiązanie, o którym nie wspomniano.

Ze wszystkimi zastrzeżeniami dotyczącymi używania wyrażenia regularnego do parsowania html, oto prosty sposób na zrobienie tego.

Metoda Perl/PCRE

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

demo

ogólne rozwiązanie

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

W tej wersji, tekst zastępuje się ujęte w grupie 1, a zastąpienie odbywa się przez proste wywołanie zwrotne lub lambda.

demo

referencyjny

  1. How to match pattern except in situations s1, s2, s3
  2. Dla implementacji kodu zobaczyć przykłady kodu w How to match a pattern unless...
+0

Najważniejszą częścią dla mnie wiedzieć '$ otrzymuje = preg_replace_callback ( \t $ regex \t funkcji ($ m) {if (empty ($ M [1])) powrót $ m [0], \t \t \t \t else return "Superman";}, \t $ subject); '. Muszę więc zwrócić 'm [0]', jeśli 'm [1]' jest puste. Naprawdę miło wiedzieć. Dziękuję Ci! – mgutt

4

To nie ma sensu, aby umieścić uprzedzona przed meczem.Więc po to odpowiednik protist odpowiedź:

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

również od < nie wolno leniwy mecz ? jest zbędny, więc jej również równoważne

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

Wybiera wszystkie Test że nie są przestrzegane przez an </a> bez symbolu < pomiędzy. Z tego powodu test, który pojawi się przed lub po każdym <a ...> .. </a> zostanie zastąpiony.

jednak pamiętać, że

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

zostanie zmieniona na

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

Aby złapać, że można zmienić regex

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

który wykonuje następujące czynności:

Wybierz każde słowo Test, po którym nie występuje ciąg znaków ***</a>, w którym po *** po znaku nie występuje <a.

Należy pamiętać, że tutaj leniwy mecz ? ma sens.

protist powiedział

Ponadto, za pomocą Wyrażenia regularne na surowego HTML nie jest zalecane.

Zgadzam się z tym. Problem polega na tym, że powodowałoby to problemy, gdyby tag nie był zamknięty lub otwarty. Na przykład wszystkie wymienione tutaj rozwiązania zmieni

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

do

Lorem Test dolor Test <strong>dolor</strong></a> eirmod 1234 dolores sea 1234 takimata 
Powiązane problemy