Imposible mirar detrás de una referencia

Desde mi entendimiento,

(.)(?<!\1) 

nunca debe coincidir En realidad, preg_replace de php incluso se niega a comstackr esto y también lo hace el gsub de gsub . Sin embargo, el módulo de re python parece tener una opinión diferente:

 import re test = 'xAAAAAyBBBBz' print (re.sub(r'(.)(?<!\1)', r'(\g)', test)) 

Resultado:

 (x)AAAA(A)(y)BBB(B)(z) 

¿Puede alguien proporcionar una explicación razonable para este comportamiento?

Actualizar

Este comportamiento parece ser una limitación en el módulo re . El módulo regex alternativo parece manejar grupos en aserciones correctamente:

 import regex test = 'xAAAAAyBBBBz' print (regex.sub(r'(.)(?<!\1)', r'(\g)', test)) ## xAAAAAyBBBBz print (regex.sub(r'(.)(.)(?<!\1)', r'(\g)', test)) ## (xA)AAA(Ay)BBB(Bz) 

Tenga en cuenta que, a diferencia de pcre , regex también permite la visualización de ancho variable:

 print (regex.sub(r'(.)(?<![AZ]+)', r'(\g)', test)) ## (x)AAAAA(y)BBBB(z) 

Eventualmente, las regex se incluirán en la biblioteca estándar, como se menciona en PEP 411 .

Esto parece una limitación (buena forma de decir “error”, como aprendí de una llamada de soporte con Microsoft) en el módulo de Python re .

Supongo que tiene que ver con el hecho de que Python no admite aserciones de mirada de longitud variable, pero no es lo suficientemente inteligente como para darse cuenta de que \1 siempre será de longitud fija. No puedo decir por qué no se queja de esto al comstackr la expresión regular.

Curiosamente:

 >>> print (re.sub(r'.(?)', test)) (x)(A)(A)(A)(A)(A)(y)(B)(B)(B)(B)(z) >>> >>> re.compile(r'(.*)(? 

Por lo tanto, es mejor que no use las referencias inversas en las afirmaciones detrás de Python. El aspecto positivo no es mucho mejor (también coincide aquí como si fuera un aspecto positivo):

 >>> print (re.sub(r'(.)(?<=\1)', r'(\g<0>)', test)) x(A)(A)(A)(A)Ay(B)(B)(B)Bz 

Y ni siquiera puedo adivinar qué está pasando aquí:

 >>> print (re.sub(r'(.+)(?<=\1)', r'(\g<0>)', test)) x(AA)(A)(A)Ay(BB)(B)Bz