2010-12-20 11 views
8

tengo una cadena que podría tener este aspectopitón expresión regular reemplazar parte de una cadena coincidente

"myFunc('element','node','elementVersion','ext',12,0,0)" 

Actualmente estoy comprobando su validez utilizando, que funciona bien

myFunc\((.+?)\,(.+?)\,(.+?)\,(.+?)\,(.+?)\,(.+?)\,(.+?)\) 

ahora i' Me gusta reemplazar cualquier cadena que esté en el 3er parámetro. desafortunadamente no puedo usar un stringreplace en cualquier subcadena en la 3ra posición ya que la misma 'subcadena' podría estar en cualquier otro lugar en esa cadena.

con esto y un re.findall,

myFunc\(.+?\,.+?\,(.+?)\,.+?\,.+?\,.+?\,.+?\) 

yo era capaz de obtener el contenido de la subcadena en la tercera posición, pero re.sub no reemplaza la cadena a la que sólo me devuelve la cadena i desee reemplazar con:/

aquí está mi código

myRe = re.compile(r"myFunc\(.+?\,.+?\,(.+?)\,.+?\,.+?\,.+?\,.+?\)") 
val = "myFunc('element','node','elementVersion','ext',12,0,0)" 

print myRe.findall(val) 
print myRe.sub("noVersion",val) 

alguna idea de lo que me he perdido?

gracias! Seb

+2

La variedad de respuestas aquí me lleva a creer que la revuelta Pythonic contra el lema TIMTOWTDI de Perl fue algo equivocado. :) –

Respuesta

1

Si usted quiere hacer esto sin usar expresiones regulares:

>>> s = "myFunc('element','node','elementVersion','ext',12,0,0)" 
>>> l = s.split(",") 
>>> l[2]="'noVersion'" 
>>> s = ",".join(l) 
>>> s 
"myFunc('element','node','noVersion','ext',12,0,0)" 
+1

¿qué pasa si primero arg es 'ele, ment'? –

+3

Luego, todas las respuestas, incluidas las de expresión regular, fallan. :) – dheerosaur

+0

¡Tienes razón! es por eso que creo que un analizador es más adecuado para esta tarea que una expresión regular. –

7

En re.sub, es necesario que especifique una sustitución de toda la cadena coincidente. Eso significa que necesita repetir las partes que no desea reemplazar. Esto funciona:

myRe = re.compile(r"(myFunc\(.+?\,.+?\,)(.+?)(\,.+?\,.+?\,.+?\,.+?\))") 
print myRe.sub(r'\1"noversion"\3', val) 
3

Si su única herramienta es un martillo, todos los problemas se ven como clavos. Una expresión regular es un martillo poderoso, pero no es la mejor herramienta para cada tarea.

Algunas tareas son manejadas mejor por un analizador. En este caso, la lista de argumentos de la cadena es igual que una tupla Python, sou puede hacer trampa: utilizar el analizador incorporado Python:

>>> strdata = "myFunc('element','node','elementVersion','ext',12,0,0)" 
>>> args = re.search(r'\(([^\)]+)\)', strdata).group(1) 
>>> eval(args) 
('element', 'node', 'elementVersion', 'ext', 12, 0, 0) 

Si no se puede confiar en la entrada ast.literal_eval es más seguro que eval para esto. Una vez que tenga la lista de argumentos en la cadena deconstruida, creo que puede encontrar la manera de manipularla y volver a montarla, si es necesario.

2

Lea la documentación: re.sub devuelve una copia de la cadena donde cada aparición del patrón completo se reemplaza con la sustitución. En ningún caso puede modificar la cadena original, porque las cadenas de Python son inmutables.

Trate de usar preanálisis y mirar detrás afirmaciones para construir una expresión regular que sólo coincide con el elemento en sí:

myRe = re.compile(r"(?<=myFunc\(.+?\,.+?\,)(.+?)(?=\,.+?\,.+?\,.+?\,.+?\))") 
+1

Si hay alguna posibilidad de que un argumento contenga una coma, el enfoque de expresiones regulares se vuelve más y más difícil. –

Cuestiones relacionadas