expresión regular de Python que reemplaza parte de una cadena coincidente

Tengo una cadena que podría tener este aspecto

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

Actualmente estoy comprobando la validez utilizando, lo que funciona bien

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

ahora me gustaría reemplazar cualquier cadena que esté en el tercer parámetro. desafortunadamente no puedo usar un stringreplace en cualquier subcadena en la tercera posición ya que la misma ‘subcadena’ podría estar en cualquier otro lugar de esa cadena.

con esto y un re.findall,

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

Pude obtener el contenido de la subcadena en la tercera posición, pero re.sub no reemplaza la cadena, solo me devuelve la cadena que quiero 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

En re.sub, debe especificar una sustitución para 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) 

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

Algunas tareas son mejor manejadas por un analizador. En este caso, la lista de argumentos en la cadena es como una tupla de Python, si puede hacer trampa: use el analizador incorporado de 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 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 decontrucida, creo que puede descubrir cómo manipularla y volverla a ensamblar, si es necesario.

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

Intente usar aseveraciones de anticipación y de retrospectiva para construir una expresión regular que solo coincida con el elemento en sí:

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

Si quieres hacer esto sin usar regex:

 >>> 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)" 

¿Has intentado usar grupos con nombre? http://docs.python.org/howto/regex.html#search-and-replace

Esperemos que eso te permita apuntar al tercer partido.