re.sub('a(b)','d','abc') produce dc , no adc .
¿Por qué re.sub reemplaza todo el grupo de captura, en lugar de solo capturar el grupo '(b)'?
Porque se supone que reemplaza toda la aparición del patrón:
Devuelve la cadena obtenida al reemplazar las ocurrencias no superpuestas del extremo izquierdo del patrón en la cadena por el reemplazo repl.
Si fuera a reemplazar solo algún subgrupo, entonces las expresiones regulares complejas con varios grupos no funcionarían. Hay varias soluciones posibles:
re.sub('ab', 'ad', 'abc') - mi favorito, ya que es muy legible y explícito.re.sub('(a)b', r'\1d', 'abc')repl y haga que procese el objeto Match y devuelva el resultado requerido.re.sub('(?<=a)b', r'd', 'abxb') produce adxb . El ?<= al comienzo del grupo dice "es una anticipación".Porque eso es exactamente lo que re.sub() doc te dice que debe hacer:
'a(b)' dice "coincide con 'a', con 'b' final opcional". (Podría coincidir con 'a' por sí solo, pero no hay forma de que pueda coincidir con 'b' por sí solo como parece esperar. Si quiso decir eso, use un (a)??b no codicioso). Si desea el resultado deseado, necesitaría una coincidencia no codiciosa en '(a)??' :
>>> re.sub('(a)??b','d','abc') 'dc'Soy consciente de que esto no responde estrictamente a la pregunta OP, pero esta pregunta puede ser difícil de buscar en Google (inundada por \ 1 explicación ...)
para aquellos que como yo vinieron aquí porque les gustaría reemplazar un grupo de captura que no es el primero por una cadena, sin un conocimiento especial de la cadena ni de la expresión regular:
#find offset [start, end] of a captured group within string r = regex.search(oldText).span(groupNb) #slice the old string and insert replacementText in the middle newText = oldText[:r[0]] + replacementText + oldText[r[1]:]Sé que es el comportamiento deseado, pero aún no entiendo por qué re.sub no puede especificar el grupo de captura real que debe sustituir en...