Regex per stringa che non termina con il suffisso dato

Non sono stato in grado di trovare una regex corretta per abbinare qualsiasi stringa che non termina con alcune condizioni. Ad esempio, non voglio abbinare qualcosa che termina con un a .

Questo corrisponde

 b ab 1 

Questo non corrisponde

 a ba 

So che la regex dovrebbe terminare con $ per segnare la fine, anche se non so cosa dovrebbe precederlo.

Modifica : la domanda originale non sembra essere un esempio legittimo per il mio caso. Quindi: come gestire più di un personaggio? Dì qualcosa che non termina con ab ?

Sono stato in grado di risolvere questo problema, usando questo thread :

 .*(?:(?!ab).).$ 

Anche se il lato negativo di questo è, non corrisponde a una stringa di un personaggio.

Non ci dai la lingua, ma se il tuo supporto per l’espressione regolare sembra dietro l’asserzione , questo è ciò di cui hai bisogno:

 .*(?< !a)$ 

(?< !a) è un'asserzione negata che garantisce che prima della fine della stringa (o riga con il modificatore m ), non c'è il carattere "a".

Guardalo qui su Regexr

Puoi anche estenderlo facilmente con altri personaggi, poiché questo controllo per la stringa e non è una class di caratteri.

 .*(?< !ab)$ 

Ciò corrisponderebbe a tutto ciò che non termina con "ab", vederlo su Regexr

Usa il simbolo no ( ^ ):

 .*[^a]$ 

Se metti il ​​simbolo ^ all’inizio delle parentesi, significa “tutto tranne le cose tra parentesi”. $ è semplicemente un’ancora fino alla fine.

Per più personaggi , basta metterli tutti nel proprio set di caratteri:

 .*[^a][^b]$ 

Per cercare file che non finiscono con “.tmp” usiamo la seguente espressione regolare:

 ^(?!.*[.]tmp$).*$ 

Testato con Regex Tester dà il seguente risultato:

inserisci la descrizione dell'immagine qui

 .*[^a]$ 

la regex di sopra corrisponderà a stringhe che non terminano con a .

Prova questo

 /.*[^a]$/ 

[] Denota una class di caratteri e la ^ inverte la class di caratteri in modo che corrisponda a tutto tranne una a .

Tutto ciò che corrisponde a qualcosa che termina con un — .*a$ Quindi, quando si abbina la regex, si annulla la condizione o in alternativa si può anche fare .*[^a]$ dove [^a] significa tutto ciò che not a è not a

La domanda è vecchia ma non sono riuscito a trovare una soluzione migliore. Inserisco il mio qui. Trova tutte le unità USB ma non elenca le partizioni , rimuovendo così la “parte [0-9]” dai risultati. Ho finito per fare due grep, l’ultimo nega il risultato:

 ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -vE "part[0-9]*$" 

Questo risulta sul mio sistema:

 pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0 

Se voglio solo le partizioni che potrei fare:

 ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -E "part[0-9]*$" 

Dove ottengo:

 pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part1 pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part2 

E quando lo faccio:

 readlink -f /dev/disk/by-path/pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0 

Ottengo:

 /dev/sdb 

La risposta accettata va bene se è ansible utilizzare i lookaround. Tuttavia, esiste anche un altro approccio per risolvere questo problema.

Se consideriamo la regex ampiamente proposta per questa domanda:

.*[^a]$

Troveremo che funziona quasi . Non accetta una stringa vuota, che potrebbe essere un po ‘scostante. Tuttavia, questo è un problema minore quando si ha a che fare con un solo personaggio. Tuttavia, se vogliamo escludere un’intera stringa, ad es. “Abc”, allora:

.*[^a][^b][^c]$

non lo farò. Ad esempio, non accetterà ac.

C’è una soluzione facile per questo problema però. Possiamo semplicemente dire:

.{,2}$|.*[^a][^b][^c]$

o versione più generalizzata:

.{,n-1}$|.*[^firstchar][^secondchar]$ dove n è la lunghezza della stringa che vuoi proibire (per abc è 3), e firstchar , secondchar , … sono i primi, secondi. .. nth caratteri della stringa (per abc sarebbe a , quindi b , quindi c ).

Questo deriva da una semplice osservazione che una stringa che è più corta del testo non vietato non può contenere questo testo per definizione. Quindi possiamo accettare tutto ciò che è più breve (“ab” non è “abc”), o qualcosa abbastanza lungo da consentirci di accettare ma senza la fine.

Ecco un esempio di find che eliminerà tutti i file che non sono .jpg:

find . -regex '.{,3}$|.*[^.][^j][^p][^g]$' -delete