2013-08-15 6 views
6

Ho pensato di capire come funzionano gli operatori di espressioni regolari, ma ora sono davvero confuso. Nel esempio semplificato, ho due stringhe:Come funziona l'operatore (?!) In regex?

mail.wow.no-1.com 
mail.ololo.wow.com 

voglio abbinare primo, non il secondo. E sto scrivendo espressioni regolari (versione semplificata) come questo:

^mail\.(.*)(?!\.wow\.com)$ 

E quando corro in Metodo di JS su entrambi questi esempi, si restituisce semplicemente falso (in sublimi 2 regex ricerca mette in evidenza entrambe le stringhe, che significa entrambe le stringhe corrispondono)

So che posso eseguire l'espressione regolare di inversione, che corrisponderà al secondo e fare la logica a seconda di questo, ma voglio solo capire come funzionain regex e cosa sto facendo male.

Grazie.

+4

http://www.regular-expressions.info/lookaround.html – Bergi

+1

Generalmente trovo il look-behind negativo più facile da capire, ma sfortunatamente questo è JavaScript :) –

risposta

8

Hai bisogno di un .* all'interno del lookahead (e spostarlo davanti alla .* al di fuori del lookahead):

^mail(?!.*\.wow\.com)\.(.*)$ 

caso contrario, i controlli guardano avanti solo alla fine della stringa. E ovviamente, alla fine della stringa, non ci può mai essere un .wow.com. Si potrebbe altrettanto bene sposta il lookahead per l'inizio del modello ora:

^(?!.*\.wow\.com)mail\.(.*)$ 

Working demo.

Quest'ultima variante è un po 'meno efficiente, ma ho trovato i modelli un po' più facile da leggere se lookaheads che interessano la l'intera stringa è tutto all'inizio del pattern.

+0

Informativo e funziona, grazie! – kibin

+1

Inoltre, è possibile trovare http://tinyurl.com/m8672z9 utile quando si tenta di comprendere espressioni regolari complesse – ForbesLindesay

3

È un zero width assertion. È una prospettiva negativa.

Cosa dice: in questa posizione, non è possibile che venga.

Quindi, ad esempio (?!q) significa, la lettera q non può seguire al momento.

1

Un esame di questo URL è che cerca "posta". quindi quanti più caratteri possibili, quindi controlla se tra quello (cioè la fine della stringa) e la fine dello schermo se ".wow.com" esiste.

^mail\.(.*)(?!\.wow\.com)$ 

Invece, riordinare in modo che esso controlla se ".wow.com" viene dopo 'la posta.'.

^mail\.(?!.*\.wow\.com)(.*)$ 
3

Quello che vuoi è

^mail\.(?!.*\.wow\.com$).*$ 

Come altri hanno dichiarato, l'è un negativo di ampiezza zero look-ahead asserzione (?!); non corrisponde a nessun numero di caratteri, ma vede i caratteri successivi e si assicura che non corrispondano a ciò che è contenuto tra parentesi.

Il Javascript ha copiato la sintassi delle espressioni regolari da Perl; questi sono generalmente noti come PCRE o espressioni regolari compatibili con Perl; tuttavia, Javascript ha solo un aspetto positivo, cioè vedono da questo punto in avanti; Perl ha anche negativo di ampiezza zero look-dietro, che avrebbe funzionato come il tuo esempio originale, e più facile in questo caso

# this is how it could be done in Perl 
^mail\..*(?<!\.wow\.com)$ 

Tuttavia JavaScript ha scelto di non supportare lookbehinds.