2011-06-30 11 views
95

tengo algo como esto:Cómo comprobar si una cadena contiene un elemento de una lista en Python

extensionsToCheck = ['.pdf', '.doc', '.xls'] 

for extension in extensionsToCheck: 
    if extension in url_string: 
     print(url_string) 

Me pregunto cuál sería la forma más elegante de hacer esto en Python (sin utilizar la de lazo)? Estaba pensando en algo como esto (como de C/C++), pero que no funcionó:

if ('.pdf' or '.doc' or '.xls') in url_string: 
    print(url_string) 
+2

utilizar una lista de comprensión –

+0

@AndreasJung había una caja. Pensaste fuera de eso. – Pyderman

+2

Posible duplicado de [Comprobar si existen varias cadenas en otra cadena] (http://stackoverflow.com/questions/3389574/check-if-multiple-strings-exist-in-another-string) – GingerPlusPlus

Respuesta

198

uso de un generador junto con any, que a cortocircuitos en la primera verdad:

if any(ext in url_string for ext in extensionsToCheck): 
    print(url_string) 

EDIT: veo esta respuesta ha sido aceptada por la OP. Aunque mi solución puede ser una solución "suficientemente buena" para su problema particular, y es una buena forma general de comprobar si se encuentran cadenas de una lista en otra cadena, tenga en cuenta que esto es todo lo que hace esta solución. No le importa donde se encuentra la cadena. Si esto es importante, como suele ser el caso con las URL, debería consultar la respuesta de @Wladimir Palant, o corre el riesgo de obtener falsos positivos.

+1

esto era exactamente lo que estaba buscando. en mi caso, no importa en qué parte de la cadena está la extensión. gracias – pootzko

+0

Gran sugerencia. Usando este ejemplo, así es como compruebo si alguno de los argumentos coincide con los conocidos indicadores de ayuda: any ([x.lower() en ['-?', '- h', '- help', '/ h '] para x en sys.argv [1:]]) –

+0

@ AX-Labs usando comprensiones de listas dentro de 'any' anulará algunas de las posibles ganancias que proporciona el cortocircuito, porque la lista completa deberá construirse en todos los casos . Si usa la expresión sin corchetes ('any (x.lower() en ['-?', '- h', '- help', '/ h'] para x en sys.argv [1:]) '), la parte' x.lower() en [...] 'solo se evaluará hasta que se encuentre un valor True. –

2

Comprobar si coincide con esta expresión regular:

'(\.pdf$|\.doc$|\.xls$)' 

Nota: Si las extensiones no están al final de la url, eliminar los $ caracteres, pero no debilite ligeramente

+1

Es una URL, ¿qué pasa si tiene una cadena de consulta? –

+0

import re re.search (pattern, your_string) – juankysmith

+0

Si bien esta respuesta funciona para el caso específico, no es escalable o genérica. necesitarías una expresión regular larga para cada patrón que quieras unir. – Dannid

12

es mejor analizar la URL correctamente - de esta manera usted puede manejar http://.../file.doc?foo y http://.../foo.doc/file.exe correctamente.

from urlparse import urlparse 
import os 
path = urlparse(url_string).path 
ext = os.path.splitext(path)[1] 
if ext in extensionsToCheck: 
    print(url_string) 
22
extensionsToCheck = ('.pdf', '.doc', '.xls') 

'test.doc'.endswith(extensionsToCheck) # returns True 

'test.jpg'.endswith(extensionsToCheck) # returns False 
+1

este es inteligente - ¡No sabía que las tuplas podían hacer eso !, pero solo funciona cuando su subcadena está anclada a un extremo de la cadena. – Dannid

+1

Manera genial. Solo desearía que hubiera algo como "contiene" en lugar de solo beginwith o endswith – BrDaHa

2

Usa la lista de comprensiones si quieres una solución de una sola línea. El siguiente código devuelve una lista que contiene la url_string cuando tiene las extensiones .doc, .pdf y .xls o devuelve la lista vacía cuando no contiene la extensión.

print [url_string for extension in extensionsToCheck if(extension in url_string)] 

NOTA: Esto es sólo para comprobar si contiene o no, y no es útil cuando se quiere extraer la palabra coincidencia exacta de las extensiones.

+0

Si bien este código puede responder a la pregunta, proporcionar un contexto adicional sobre por qué y/o cómo responde la pregunta mejoraría significativamente su valor a largo plazo. Por favor [edite] su respuesta para agregar alguna explicación. – CodeMouse92

+0

Esto es más fácil de leer que cualquier solución, en mi opinión es una de las mejores soluciones posibles para esa pregunta. –

+0

Este es superior a la solución 'any()' en mi opinión, ya que puede modificarse para devolver el valor de coincidencia específico, así: 'print [extensión para extensión en extensiones Para comprobar si (extensión en url_string)]' (ver mi respuesta para obtener detalles adicionales y cómo extraer la _word_ coincidente así como el patrón de url_string) – Dannid

0

Esta es una variante de la respuesta de comprensión de lista dada por @psun.

Al cambiar el valor de salida, en realidad se puede extraer el patrón coincidente de la lista por comprensión (algo que no es posible con el enfoque any() por @ Lauritz-v-Thaulow)

extensionsToCheck = ['.pdf', '.doc', '.xls'] 
url_string = 'http://.../foo.doc' 

print [extension for extension in extensionsToCheck if(extension in url_string)] 

['.doc '] `

Puede insertar además una expresión regular si se quiere recoger información adicional una vez que el patrón emparejado se conoce (esto podría ser útil cuando la lista de patrones permitidos es demasiado tiempo para escribir en una sola expresión regular patrón)

print [re.search(r'(\w+)'+extension, url_string).group(0) for extension in extensionsToCheck if(extension in url_string)] 

['foo.doc']

Cuestiones relacionadas