2012-04-07 35 views
5

que tienen este patrón escrito¿Patrón Regex que no coincide con ciertas extensiones?

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

Sin embargo hay un problema - este patrón coincide con file.name.jpg (2 puntos)

Funciona correctamente (no coincide) en filename.jpg. Estoy intentando descubrir cómo hacer que no coincida con CUALQUIER archivo .jpg incluso si el nombre del archivo tiene 2 o más puntos en él. Intenté usar una mirada hacia atrás, pero Python se queja de no usar un ancho fijo (que no estoy exactamente seguro de lo que eso significa, pero el nombre del archivo será de longitud variable.)

Respuesta

10

Esto debería funcionar: ^.*\.(?!jpg$|png$)[^.]+$

+0

¡buen trabajo! excelente – yash

3

Use os.path 's funciones hábiles para dividir correctamente la ruta de archivo en componentes para facilitar el análisis sintáctico:

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

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

Prueba esta expresión regular (no lo haga lo hace exactamente lo contrario de lo que quiere hacer.):

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

No tengo acceso a Python, es el motor de expresiones regulares de Python, pero solo tengo acceso a un archivo de configuración JSON para poner la expresión regular allí para un programa de Python. Eliminé la etiqueta de Python para evitar confusiones. –

+0

Ver mi edición. Creo que debería funcionar – Blender

+0

Parece que su expresión regular está tratando de excluir cadenas que * contienen * '.jpg' o' .png', pero creo que la idea es excluir cualquier cosa que * termine * con '.jpg' o '.png'. La expresión regular del OP está fallando porque tanto el lookahead como el final '. + $' Pueden coincidir después del primer '.' en' file.name.jpg'. Cambiar eso a '[^.] + $', Como lo hizo @bereal, obliga a que la búsqueda anticipada se aplique solo a la secuencia final de punto o cualquier cosa. –

0

Por favor, intente

 
    .*\.(jpg$|png$) 

Emparejará correctamente en filename.jpg. Si intenta averiguar cómo hacer coincidir CUALQUIER archivo .jpg incluso si el nombre del archivo tiene 2 o más puntos, funcionará bien.
Al usar la secuencia de comandos python, asegúrese de estar utilizando el tipo correcto de división. el diferente tipo de split viz rsplit (división derecha) e lsplit (división izquierda).

+0

Lo tienes al revés: la expresión regular NO debe coincidir con 'filename.jpg' O' file.name.png'. 'filename.txt' o' file.name.foo' están bien, supongo. –

1

parece que casi lo tenía:

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

Según mis pruebas (en Java) que obtener estos resultados:

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 

Si esto no es lo que quería peticiones actualizar su pregunta con tus expectativas.

1

Si sólo se preocupan de que la cadena no termina con .jpg o .png, puede utilizar esto:

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

El ^.+ no es estrictamente necesario, pero dependiendo de cómo el analizador JSON que se codifica podría necesitar forzar a la expresión regular a consumir toda la cadena. Si está utilizando la expresión regular para otras validaciones así, es posible que desee algo más elaborado, como:

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

Probablemente ha intentado usar (?<!\.jpg|\.png), lo que no funciona porque el sabor de expresiones regulares de Python es uno de los más restrictivo cuando se trata de mirar atrás. PHP y Ruby 1.9+ lo aceptarían porque cada una de las alternativas tiene una longitud fija. Ni siquiera tienen que ser la misma longitud ; (?<!\.jpg|\.jpeg|\.png) funcionaría también. Simplemente no intente factorizar el punto, como en (?<!\.(?:jpg|jpeg|png)); la alternancia tiene que estar en el nivel superior de la mirada hacia atrás.

Java aceptaría la versión factorizada, ya que hace un poco más de trabajo en tiempo de compilación para determinar el número máximo de caracteres que el lookbehind podría necesitar para coincidir. Sin embargo, la expresión lookbehind debe ser bastante simple y no puede usar los cuantificadores + o *. Finalmente, los sabores de .NET y JGSoft no imponen ninguna restricción en las búsquedas. Pero Python hace un intento muy simple de averiguar la cantidad exacta de caracteres que el aspecto subyacente necesita para coincidir, generando ese mensaje de error críptico cuando falla.

+0

Gracias, gran respuesta. –

Cuestiones relacionadas