2012-09-19 12 views
7

ho la seguente stringa:Regex sostituire il testo, ma esclude quando il testo è tra tag specifico

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. 

ora vorrei sostituire la stringa di fuori 'Test' di tag un non tra i tag (ad esempio sostituiti con '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. 

ho iniziato con questa espressione regolare: (?!<a[^>]*>)(Test)([^<])(?!</a>)

Ma due problemi non vengono risolti:

  1. Il testo 'Test' viene anche sostituito all'interno Tag (ad esempio)
  2. dice il testo tra il tag non corrisponde esattamente al testo cercato, sarà anche sostituito (es. <a href="http://url">Test xyz</a>)

Spero che qualcuno abbia una soluzione per risolvere questo problema.

risposta

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

stesso di zb226, ma ottimizzato con una partita pigro

Inoltre, utilizzando espressioni regolari su RAW HTML è non consigliato.

+0

ho aggiunto anche la bandiera \ b per abbinare una parola di confine: (?!? ] *>) (\ BTest \ b) (?! [^ <]*?) – Weri

+0

Ciò dovrebbe dare all'applicatore di regex più funzioni. Inoltre, non dovrebbe influire negativamente sulle tue corrispondenze, a patto che '_Test_, _Test, o Test_' non siano nel tuo documento (e presumendo che non ti preoccupi di abbinarle se lo fossero). – protist

+0

Il look prima di Test e la partita pigra sono privi di significato. Vedi la mia risposta. – Adam

3

Questo dovrebbe fare il trucco:

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

Provate voi stessi on regexr.

2

Resuscitare questa antica domanda perché aveva una soluzione semplice che non era menzionata.

Con tutti i disclaimer sull'utilizzo di regex per analizzare html, ecco un modo semplice per farlo.

Metodo per Perl/PCRE

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

demo

soluzione generale

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

In questa versione, il testo da sostituire è catturato nel Gruppo 1 e il la sostituzione viene eseguita da una semplice richiamata o lambda.

demo

Riferimento

  1. How to match pattern except in situations s1, s2, s3
  2. Per l'implementazione di codice vedere gli esempi di codice in How to match a pattern unless...
+0

La parte più importante per me è stato quello di conoscere '$ sostituito = preg_replace_callback ( \t $ regex, \t funzione ($ m) {if (empty ($ m [1])) return $ m [0]; \t \t \t \t \t else return "Superman";}, \t $ subject); '. Quindi ho bisogno di restituire 'm [0]' se 'm [1]' è vuoto. Davvero bello sapere. Grazie! – mgutt

4

Non ha senso mettere un lookahead prima della partita.Così il seguente è equivalente a protista risposta:

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

anche perché < non è consentito il match pigro ? è superfluo, per cui il suo anche equivalente a

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

seleziona tutti i Test che non sono seguiti da un </a> senza il simbolo < in mezzo. Questo è il motivo per cui il test che appare prima o dopo qualsiasi <a ...> .. </a> verrà sostituito.

Tuttavia, si noti che

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

sarebbe cambiato per

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

Per raggiungere che si possa cambiare la vostra regex per

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

che esegue le seguenti operazioni:

Selezionare ogni parola Test non seguita da una stringa ***</a> in cui ogni carattere in *** non è seguito da <a.

Si noti che qui la corrispondenza pigra ? ha senso.

protista detto

Inoltre, utilizzando espressioni regolari su HTML grezzo non è raccomandato.

Sono d'accordo. Un problema è che causerebbe problemi se un tag non è chiuso o aperto. Per esempio tutte le soluzioni di cui qui cambierebbero

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

a

Lorem Test dolor Test <strong>dolor</strong></a> eirmod 1234 dolores sea 1234 takimata 
Problemi correlati