2011-02-10 10 views
10

Tengo una lista de patrones exactos que deseo buscar en una cadena dada. Actualmente tengo una solución realmente mala para tal problema.Cómo hacer coincidir cadenas "múltiples" exactas en Python

pat1 = re.compile('foo.tralingString') 
mat1 = pat1.match(mystring) 

pat2 = re.compile('bar.trailingString') 
mat2 = pat2.match(mystring) 

if mat1 or mat2: 
    # Do whatever 

pat = re.compile('[foo|bar].tralingString') 
match = pat.match(mystring) # Doesn't work 

La única condición es que tengo una lista de cadenas que deben coincidir exactamente. Cuál es la mejor solución posible en Python.

EDITAR: Los patrones de búsqueda tienen algunos patrones finales comunes.

Respuesta

16

Se podría hacer una expresión regular trivial que combina los dos:

pat = re.compile('foo|bar') 
if pat.match(mystring): 
    # Do whatever 

A continuación, puede ampliar la expresión regular para hacer lo que es necesario, mediante el | separador (que significa o en la sintaxis de expresiones regulares)

Editar: Basado en su reciente edición, esto debe hacerlo por usted:

pat = re.compile('(foo|bar)\\.trailingString'); 
if pat.match(mystring): 
    # Do Whatever 

El [] es una clase de caracteres. Entonces su [foo|bar] coincidiría con una cadena con una de los caracteres incluidos (ya que no hay * o + o? Después de la clase). () es el gabinete para un subpatrón.

+0

En realidad, el problema es un poco más complicado. Mis patrones de búsqueda son como '1. foo.trailingString 2. bar.trailingString'. Intenté hacer '[foo | bar] .trailingString', pero eso falla. – Neo

+0

@Neo: eso cambia la pregunta, ¿verdad? intente '(foo | bar) .trailingString' (aunque no estoy 100% seguro de la sintaxis de la expresión regular de Python) ... – ircmaxell

+0

@ircmaxell: Python tiene una sintaxis similar a PCRE con solo algunas pequeñas diferencias, creo. – BoltClock

7

Tiene razón al usar | pero está usando una clase de caracteres [] en lugar de un subpatrón (). Prueba esta expresión regular:

r = re.compile('(?:foo|bar)\.trailingString') 

if r.match(mystring): 
    # Do stuff 

respuesta Antiguo

Si usted quiere hacer subcadena de juegos compatibles no se debe utilizar expresiones regulares.

trate de usar in lugar:

words = ['foo', 'bar'] 

# mystring contains at least one of the words 
if any(i in mystring for i in words): 
    # Do stuff 
+0

Mire la edición. Todos los patrones de búsqueda tienen algunas partes finales comunes. Así que esperaba usar Re de alguna manera. – Neo

+0

@Neo: he editado mi respuesta. – BoltClock

0

quizá

any([re.match(r, mystring) for r in ['bar', 'foo']]) 

Estoy asumiendo patrones de coincidencia será más complejo que foo o la barra; si no lo son, sólo tiene que utilizar

if mystring in ['bar', 'foo']: 
1

Uso '|' en su expresión regular. Significa 'O'. Hay una mejor manera también, cuando se quiere re.escape sus cadenas

pat = re.compile('|'.join(map(re.escape, ['foo.tralingString','bar.tralingString','something.else']))) 
1

¿Quieres buscar patrones o cadenas?La mejor solución para cada uno es muy diferente:

# strings 
patterns = ['foo', 'bar', 'baz'] 
matches = set(patterns) 

if mystring in matches:  # O(1) - very fast 
    # do whatever 


# patterns 
import re 
patterns = ['foo', 'bar'] 
matches = [re.compile(pat) for pat in patterns] 

if any(m.match(mystring) for m in matches): # O(n) 
    # do whatever 

Editar: Ok, que desea buscar en las cadenas exactas de longitud variable en el comienzo de una cadena de búsqueda; intente

from collections import defaultdict 
matches = defaultdict(set) 

patterns = ['foo', 'barr', 'bazzz'] 
for p in patterns: 
    matches[len(p)].add(p) 

for strlen,pats in matches.iteritems(): 
    if mystring[:strlen] in pats: 
     # do whatever 
     break 
Cuestiones relacionadas