Python 带反向引用的不可能查找

Python 带反向引用的不可能查找,python,regex,python-3.x,python-2.7,Python,Regex,Python 3.x,Python 2.7,据我了解, (.)(?<!\1) 结果: (x)AAAA(A)(y)BBB(B)(z) 有人能为这种行为提供合理的解释吗 更新 此行为出现在re模块中。替代模块似乎可以正确处理断言中的组: import regex test = 'xAAAAAyBBBBz' print (regex.sub(r'(.)(?<!\1)', r'(\g<0>)', test)) ## xAAAAAyBBBBz print (regex.sub(r'(.)(.)(?<!\1)'

据我了解,

(.)(?<!\1)
结果:

(x)AAAA(A)(y)BBB(B)(z)
有人能为这种行为提供合理的解释吗

更新 此行为出现在
re
模块中。替代模块似乎可以正确处理断言中的组:

import regex

test = 'xAAAAAyBBBBz'

print (regex.sub(r'(.)(?<!\1)', r'(\g<0>)', test))
## xAAAAAyBBBBz

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

最后,
regex
将被包括在标准库中,如中所述。

这看起来确实像是Python
re
模块中的一个限制(我从与Microsoft的一次支持电话中了解到,说“bug”很好)

我想这与Python不支持可变长度的lookbehind断言有关,但它还没有聪明到能够理解
\1
始终是固定长度的。我不能说,为什么在编译正则表达式时它不抱怨这一点

有趣的是:

>>> print (re.sub(r'.(?<!\0)', r'(\g<0>)', test))
(x)(A)(A)(A)(A)(A)(y)(B)(B)(B)(B)(z)
>>>
>>> re.compile(r'(.*)(?<!\1)') # This should trigger an error but doesn't!
<_sre.SRE_Pattern object at 0x00000000026A89C0>
>>打印(re.sub(r.(?)’,测试))
(x) (A)(A)(A)(A)(y)(B)(B)(B)(z)
>>>
>>>重新编译(r'(.*)(?)?
因此,最好不要在Python中的lookbehind断言中使用反向引用。正向lookbehind并没有好多少(它在这里也匹配,就像它是正向lookbehind一样):


>>print(re.sub(r'())(?它的匹配就像您使用的
()(?!\1)
一样。谢谢,这证实了我对这是一个bug的感觉。Python显然不是唯一一种在Lookback断言中存在反向引用问题的语言:
print (regex.sub(r'(.)(?<![A-Z]+)', r'(\g<0>)', test))
## (x)AAAAA(y)BBBB(z)
>>> print (re.sub(r'.(?<!\0)', r'(\g<0>)', test))
(x)(A)(A)(A)(A)(A)(y)(B)(B)(B)(B)(z)
>>>
>>> re.compile(r'(.*)(?<!\1)') # This should trigger an error but doesn't!
<_sre.SRE_Pattern object at 0x00000000026A89C0>
>>> print (re.sub(r'(.)(?<=\1)', r'(\g<0>)', test))
x(A)(A)(A)(A)Ay(B)(B)(B)Bz
>>> print (re.sub(r'(.+)(?<=\1)', r'(\g<0>)', test))
x(AA)(A)(A)Ay(BB)(B)Bz