2013-08-14 27 views
10

Ho i seguenti motivi da escludere.RegEx - Escludi pattern abbinati

make it cheaper 
make it cheapere 
makeitcheaper.com.au 
makeitcheaper 
making it cheaper 
www.make it cheaper 
ww.make it cheaper.com 

Ho creato un regex per abbinare uno di questi. Tuttavia, voglio ottenere tutto il resto diverso da questi. Non sono sicuro di come invertire questa regex che ho creato.

mak(e|ing) ?it ?cheaper 

Sopra il modello corrisponde a tutte le stringhe elencate. Ora voglio che corrisponda a tutto il resto. Come lo faccio?

Dalla ricerca, sembra che ho bisogno di qualcosa di simile a lookahead negativo/guardare indietro. Ma, davvero non capisco. Qualcuno può indicarmi la giusta direzione?

risposta

17

Si può semplicemente mettere in un negativo look-ahead in questo modo:

(?!mak(e|ing) ?it ?cheaper) 

Proprio come quella non è andare a lavorare anche se dal momento che, se si fa un matches , non lo farà combaciano dal momento che stai guardando avanti, in realtà non stai corrispondendo a nulla, e, se fai un find , corrisponderà molte volte, dal momento che puoi iniziare da un sacco di posti nella stringa in cui i seguenti personaggi non abbinare il sopra.

Per risolvere questo problema, a seconda di cosa si desidera fare, abbiamo 2 scelte:

  1. Se si desidera escludere tutte le stringhe che sono esattamente uno di quelli (vale a dire "rendono cheaperblahblah" non è escluso), controllare per l'avvio (^) e la fine ($) di corda:

    ^(?!mak(e|ing) ?it ?cheaper$).* 
    

    il .* (zero o più wild-card) è il luogo effettivo corrispondente prendendo. Le verifiche negative look-ahead del primo carattere.

  2. Se si desidera escludere tutte le stringhe contenenti uno di quelli, è possibile assicurarsi che il look-ahead non corrisponde prima di ogni carattere abbiniamo:

    ^((?!mak(e|ing) ?it ?cheaper).)*$ 
    

    Un'alternativa è quella di aggiungere selvaggio -card all'inizio del tuo look-ahead (esesclude tutte le stringhe che, dall'inizio della stringa, contengono qualcosa, quindi il tuo pattern), ma al momento non vedo alcun vantaggio per questo (la lunghezza arbitraria di look-ahead è anche meno probabile che sia supportata da un determinato strumento):

    ^(?!.*mak(e|ing) ?it ?cheaper).* 
    

a causa della ^ e $, sia facendo un find o un matches funziona per entrambi di quanto sopra (anche se, nel caso di matches, il ^ è opzionale e, nel caso di find, il .* all'esterno del look-ahead è facoltativo).


1: Anche se non può essere chiamato così, molte lingue hanno funzioni equivalenti a matches e find con espressioni regolari.


Quanto sopra è la risposta rigorosamente regex a questa domanda.

Un approccio migliore potrebbe essere quello di attenersi alla regex originale (mak(e|ing) ?it ?cheaper) e vedere se è possibile annullare le corrispondenze direttamente con lo strumento o la lingua che si sta utilizzando.

In Java, ad esempio, ciò comporterebbe il if (!string.matches(originalRegex)) (notare lo !, che nega il valore booleano restituito) anziché if (string.matches(negLookRegex)).

6

Il lookahead negativo, credo sia quello che stai cercando. Forse provare:

(?!.*mak(e|ing) ?it ?cheaper) 

e forse un po 'più flessibile:

(?!.*mak(e|ing) *it *cheaper) 

Solo nel caso ci siano più di uno spazio.

Problemi correlati