Ответ 1
Это выглядит как ограничение (хороший способ сказать "ошибка", как я узнал из запроса поддержки с Microsoft) в модуле Python re
.
Я предполагаю, что это связано с тем, что Python не поддерживает утверждения переменной длины, но он недостаточно умен, чтобы понять, что \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>
Поэтому лучше не использовать обратные ссылки в утверждениях lookbehind в Python. Положительный lookbehind не намного лучше (он также соответствует здесь, как если бы он был положительным взглядом):
>>> 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