2015-02-04 22 views
5

Ho questa espressione regolare che funziona quasi come previsto ...Utilizzando (<assert regex senza larghezza fissa

(?<!color:)(?<!color:)(?<!pid=[0-9][0-9][0-9][0-9][0-9])\#(\w+) 

Diciamo che questo è il mio codice html:

<span style='color: #FFAABB'><a href='?pid=55155#pid55155'>hey #hello</a></span> 

L'unica espressione regolare match: #hello che va bene, ma il punto è che non so quanti numeri saranno dopo "pid" e non posso usare "?", "*" o "{n, m}" con " (? <!) "(Non so perché)

La mia domanda è: C'è un modo per renderlo dinamico?

Si prega di non suggerire:

(?<!color:)(?<!color:)(?<!pid=[0-9])(?<!pid=[0-9][0-9])(?<!pid=[0-9][0-9][0-9])(?<!pid=[0-9][0-9][0-9][0-9])\#(\w+) 

Perché è terribile.

Ecco un esempio di lavoro:

https://www.regex101.com/r/rC2mH4/1

Grazie in anticipo :)

+1

quale lingua si sono in esecuzione? php? –

+5

sei andato completamente html-regexed. Mai andare completamente html-regexed. Usa invece un parser e risparmia il mal di testa. –

+0

Sto utilizzando la funzione MyCode dal pannello di amministrazione nella bacheca del forum MyBB.Al backend usa php ma non ho modificato niente lì, sto solo usando uno strumento. (Ecco perché non posso usare un parser xml). Sto collegando gli hashtag a Twitter nel forum. Sono sicuro che dev'essere una soluzione facile per questo. – Daii

risposta

2

Se la lingua supporta (*SKIP)(*F), allora si potrebbe utilizzare semplicemente il seguito.

(?:color:\s*|pid=\d*)#(*SKIP)(*F)|#(\w+) 

DEMO

noti che i suddetti \s partite caratteri di nuova riga anche. Quindi utilizzare \h per abbinare solo gli spazi orizzontali.

Spiegazione:

  • (?:color:\s*|pid=\d*)# corrisponde a tutti i simboli più # precedente color: e zero o più spazi o | le pid= e zero o più cifre. Quindi la parte che non vuoi è stata abbinata.

  • (*SKIP)(*F) causa la mancata corrispondenza precedente. E il pattern dopo | proverà ad abbinare i caratteri della stringa rimanente.

  • Nel nostro caso il modello dopo | è #. Quindi, #(\w+) corrisponde a tutti i tag hash desiderati.

+0

La lingua è php, proviamo. – Daii

+0

sicuro, vai avanti :-) –

+0

Cosa fa * SKIP? Non ho capito per niente – Daii

1
color:\s*#\w+|pid=\d+#\w+|(#\w+) 

Si può provare this.Just afferrare la cattura o group.See demo.This partite tutte stronzate e cattura ciò che si desidera.

https://www.regex101.com/r/rC2mH4/3

$re = "/color:\\s*#\\w+|pid=\\d+#\\w+|(#\\w+)/m"; 
$str = "<span style=\"font-weight: bold;\">test1<span style=\"color: #FFA500;\">test2</span>test3</span>#hello#how#are#you\n<span style=\"font-weight: bold;\">test1<span style=\"color: #FFA500;\">test2</span>test3</span>#lalala #hello\n<div class=\"post_body\" id=\"pid_58705\">\n<blockquote><cite><span> (Hoy 02:42)</span>Moroha escribió: <a class=\"quick_jump\" href=\"http://test.com/Thread-hello?pid=58672#pid58672\" rel=\"nofollow\">&nbsp;</a></cite>testing</blockquote></div>\npid=97589735935795358672#foobar\n<span style='color: #FFAABB'><a href='?pid=55155#pid55155'>hey #hello</a></span>"; 

preg_match_all($re, $str, $matches); 
+0

Funziona, ma @Avinash Raj è la risposta giusta. Btw, grazie. – Daii

+0

@Daii credo che entrambe siano risposte corrette. Semplicemente l'approccio è diverso. Anche se sarebbe facile da capire – vks

+0

Come ho detto, entrambi funzionano ma il modo corretto di farlo è @ modo Avatar perché è ESATTAMENTE quello che volevo. Il tuo è più simile a una soluzione alternativa. – Daii

Problemi correlati