Grupos de partido en Python

¿Hay alguna forma en Python para acceder a grupos de coincidencia sin crear explícitamente un objeto de coincidencia (u otra forma de embellecer el ejemplo a continuación)?

Aquí hay un ejemplo para aclarar mi motivación para la pregunta:

Siguiendo código perl

if ($statement =~ /I love (\w+)/) { print "He loves $1\n"; } elsif ($statement =~ /Ich liebe (\w+)/) { print "Er liebt $1\n"; } elsif ($statement =~ /Je t\'aime (\w+)/) { print "Il aime $1\n"; } 

traducido a Python

 m = re.search("I love (\w+)", statement) if m: print "He loves",m.group(1) else: m = re.search("Ich liebe (\w+)", statement) if m: print "Er liebt",m.group(1) else: m = re.search("Je t'aime (\w+)", statement) if m: print "Il aime",m.group(1) 

se ve muy incómodo (if-else-cascade, coincide con la creación de objetos).

Podría crear una pequeña clase que devuelva el resultado booleano de la coincidencia de llamada y retenga los grupos coincidentes para su posterior recuperación:

 import re class REMatcher(object): def __init__(self, matchstring): self.matchstring = matchstring def match(self,regexp): self.rematch = re.match(regexp, self.matchstring) return bool(self.rematch) def group(self,i): return self.rematch.group(i) for statement in ("I love Mary", "Ich liebe Margot", "Je t'aime Marie", "Te amo Maria"): m = REMatcher(statement) if m.match(r"I love (\w+)"): print "He loves",m.group(1) elif m.match(r"Ich liebe (\w+)"): print "Er liebt",m.group(1) elif m.match(r"Je t'aime (\w+)"): print "Il aime",m.group(1) else: print "???" 

Menos eficiente, pero más simple:

 m0 = re.match("I love (\w+)", statement) m1 = re.match("Ich liebe (\w+)", statement) m2 = re.match("Je t'aime (\w+)", statement) if m0: print "He loves",m0.group(1) elif m1: print "Er liebt",m1.group(1) elif m2: print "Il aime",m2.group(1) 

El problema con las cosas de Perl es la actualización implícita de alguna variable oculta. Eso es simplemente difícil de lograr en Python porque necesita tener una statement de asignación para actualizar realmente cualquier variable.

La versión con menos repetición (y mejor eficiencia) es esta:

 pats = [ ("I love (\w+)", "He Loves {0}" ), ("Ich liebe (\w+)", "Er Liebe {0}" ), ("Je t'aime (\w+)", "Il aime {0}") ] for p1, p3 in pats: m= re.match( p1, statement ) if m: print p3.format( m.group(1) ) break 

Una pequeña variación que algunos perlistas prefieren:

 pats = { "I love (\w+)" : "He Loves {0}", "Ich liebe (\w+)" : "Er Liebe {0}", "Je t'aime (\w+)" : "Il aime {0}", } for p1 in pats: m= re.match( p1, statement ) if m: print pats[p1].format( m.group(1) ) break 

No vale la pena mencionarlo, excepto que a veces surge de los progtwigdores de Perl.

Esto no es una solución regex.

 alist={"I love ":""He loves"","Je t'aime ":"Il aime","Ich liebe ":"Er liebt"} for k in alist.keys(): if k in statement: print alist[k],statement.split(k)[1:] 

Podrías crear una función auxiliar:

 def re_match_group(pattern, str, out_groups): del out_groups[:] result = re.match(pattern, str) if result: out_groups[:len(result.groups())] = result.groups() return result 

Y luego úsalo así:

 groups = [] if re_match_group("I love (\w+)", statement, groups): print "He loves", groups[0] elif re_match_group("Ich liebe (\w+)", statement, groups): print "Er liebt", groups[0] elif re_match_group("Je t'aime (\w+)", statement, groups): print "Il aime", groups[0] 

Es un poco torpe, pero hace el trabajo.