2012-04-07 22 views
5

Ho questo modello scrittoPattern Regex che non corrisponde ad alcune estensioni?

^.*\.(?!jpg$|png$).+$ 

Tuttavia c'è un problema - questo modello corrisponde file.name.jpg (2 punti)

Funziona correttamente (non corrisponde) su filename.jpg. Sto cercando di capire come farlo non corrisponde a QUALSIASI file .jpg anche se il nome del file contiene 2 o più punti. Ho provato ad usare un aspetto dietro, ma Python si lamenta di non usare una larghezza fissa (che non sono esattamente sicuro di cosa significhi, ma il nome del file sarà di lunghezza variabile)

risposta

10

Questo dovrebbe funzionare: ^.*\.(?!jpg$|png$)[^.]+$

+0

ottimo lavoro! eccellente – yash

3

Usa le funzioni eleganti di os.path per dividere correttamente il percorso del file in componenti per facilitare l'analisi:

filepath, filename = os.path.split(str) 
basename, extension = os.path.splitext(filename) 

if exension[1:] in ['jpg', 'png']: 
    # The extension matches 

Prova questo regex (non fatelo lo fa l'esatto opposto di ciò che si vuole fare.):

\.(jpg|png)([^\.]|$) 
+0

Non ho accesso a Python, è il motore regex di Python, ma ho solo accesso a un file di configurazione JSON per mettere l'espressione regolare lì per un programma Python. Ho rimosso il tag Python per evitare confusione. –

+0

Vedi la mia modifica. Penso che dovrebbe funzionare – Blender

+0

Il tuo regex sembra che stia cercando di escludere stringhe che * contengono * '.jpg. O' .png', ma credo che l'idea sia di escludere qualsiasi cosa che * termina * con '.jpg' o '.png'. La regex dell'OP fallisce perché sia ​​il lookahead che il finale '. + $' Possono corrispondere dopo il primo '.' in' file.name.jpg'. Cambiandolo a '[^.] + $', Come fatto da @bereal, forza il lookahead a applicarsi solo alla sequenza punto-punto finale. –

0

Prova

 
    .*\.(jpg$|png$) 

Si abbinerà correttamente filename.jpg. il tuo tentativo di capire come creare corrispondenze con QUALSIASI file .jpg anche se il nome del file contiene 2 o più punti, funzionerà correttamente.
Mentre si utilizza lo script python, assicurarsi di utilizzare il giusto tipo di divisione. il diverso tipo di split viz rsplit (right split) e lsplit (left split).

+0

L'hai reindirizzato: la regex NON deve corrispondere a 'filename.jpg' OPPURE file.name.png'. 'filename.txt' o' file.name.foo' sono a posto, presumo. –

1

Sembra quasi avuta:

.*\.(?!jpg$|png$)[^.]+ 

Secondo le mie prove (in java) ottengo questi risultati:

file.jpg - false 
file.png - false 
file.name.jpg - false 
file.name.png - false 
file.gif - true 
file.name.gif - true 
file.jpg.gif - true 
file.jpge - true 

Se questo non è quello che volevi suppliche aggiornare la tua domanda con le tue aspettative.

1

Se vi interessa soltanto che la stringa non si esaurisce con .jpg o .png, è possibile utilizzare questo:

^.+$(?<!\.jpg)(?<!\.png) 

Il ^.+ non è strettamente necessario, ma a seconda di come il parser JSON è codificato voi potrebbe essere necessario forzare la regex per consumare l'intera stringa. Se si utilizza l'espressione regolare per gli altri convalide così, si potrebbe desiderare qualcosa di più elaborato, come:

^\w+(?:\.\w+)+$(?<!\.jpg)(?<!\.png) 

Probabilmente è tentato di utilizzare (?<!\.jpg|\.png), che non avrebbe funzionato perché il sapore regex di Python è uno dei più restrittivo quando si tratta di lookbehinds. PHP e Ruby 1.9+ lo accetterebbero perché ognuna delle alternative ha una lunghezza fissa. Non devono nemmeno essere la stessa lunghezza; (?<!\.jpg|\.jpeg|\.png) funzionerebbe anche. Basta non provare a calcolare il punto, come in (?<!\.(?:jpg|jpeg|png)); l'alternanza deve essere al livello più alto del lookbehind.

Java accetta la versione con scomposizione del carico poiché fa un po 'più di lavoro in fase di compilazione per determinare il numero massimo di caratteri che il lookbehind potrebbe dover corrispondere. L'espressione lookbehind deve tuttavia essere abbastanza semplice e non può utilizzare i quantificatori + o *. Infine, i gusti .NET e JGSoft non impongono alcuna restrizione sui lookbehind. Ma Python fa un tentativo molto semplice di capire il numero esatto di caratteri che il lookbehind deve corrispondere, generando quel criptico messaggio di errore quando fallisce.

+0

Grazie, ottima risposta. –

Problemi correlati