Come negare l'intera regex?


95

Ho una regex, per esempio (ma|(t){1}). Si abbina mae te non corrisponde bla.

Voglio negare la regex, quindi deve corrispondere blae non mae t, aggiungendo qualcosa a questa regex . So di poter scrivere bla, la regex effettiva è comunque più complessa.


5
Per inciso, {1}è completamente inutile. (Se pensi che fornisca un valore, perché non scrivi ((m{1}a{1}){1}|(t){1}){1}?)
tripleee

Risposte:


100

Usa lookaround negativo: (?!pattern)

I lookaround positivi possono essere utilizzati per affermare che un pattern corrisponde. Il lookaround negativo è l'opposto: è usato per affermare che un pattern NON corrisponde. Alcuni gusti supportano le asserzioni; alcuni mettono limitazioni al lookbehind, ecc.

Collegamenti a regular-expressions.info

Guarda anche

Altri esempi

Questi sono tentativi di trovare soluzioni regex ai problemi dei giocattoli come esercizi; dovrebbero essere educativi se stai cercando di imparare i vari modi in cui puoi usare i lookaround (annidandoli, usandoli per catturare, ecc.):


2
regular-expressions.info è una dannatamente buona risorsa per tutte le cose regex.
Freiheit

Cosa hanno tutti il supporto del lookaround ? Non funziona con grep.
Lazer

Pattern.compile("(?!(a.*b))").matcher("xab").matches()dovrebbe essere true, giusto?
Karl Richter

4
Mi sembra che questo non sia corretto, vedi stackoverflow.com/questions/8610743/… per un'alternativa corretta.
Karl Richter

56

Supponendo che tu voglia disabilitare solo le stringhe che corrispondono completamente alla regex (cioè, mmblava bene, ma mmnon lo è), questo è quello che vuoi:

^(?!(?:m{2}|t)$).*$

(?!(?:m{2}|t)$)è un lookahead negativo ; dice "a partire dalla posizione corrente, i prossimi caratteri non sono mmo t, seguiti dalla fine della stringa". Lo start anchor ( ^) all'inizio assicura che il lookahead sia applicato all'inizio della stringa. Se ha successo, .*va avanti e consuma la stringa.

Cordiali saluti, se stai usando il matches()metodo Java , non hai davvero bisogno di the ^e final $, ma non fanno alcun danno. Tuttavia, $è necessario l'interno del lookahead.


2
La parte più utile di questa risposta è che devi aggiungere .*alla fine della tua regex, altrimenti rifiuterà ogni stringa.
Rav

2
L' $ interno del lookahead negativo E quello .*alla fine sono entrambi bit critici. Come sempre con le RE, una serie forte di unit test è assolutamente fondamentale per farlo bene. Questa risposta è corretta al 100%.
Tom Dibble

1
\b(?=\w)(?!(ma|(t){1}))\b(\w*)

questo è per la data regex.
la \ b serve per trovare il confine della parola.
lo sguardo positivo in avanti (? = \ w) è qui per evitare spazi.
lo sguardo negativo in avanti rispetto alla regex originale è impedire che corrisponda.
e infine il (\ w *) è quello di catturare tutte le parole che sono rimaste.
il gruppo che conterrà le parole è il gruppo 3.
il semplice (?! pattern) non funzionerà in quanto qualsiasi sottostringa corrisponderà
alla semplice ^ (?! (?: m {2} | t) $). * $ non funziona in quanto la sua granularità è piena


0

Applicalo se usi laravel.

Laravel ha un not_regex dove il campo sotto convalida non deve corrispondere all'espressione regolare data; utilizza preg_matchinternamente la funzione PHP .

'email' => 'not_regex:/^.+$/i'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.