Вопрос по python, regex, python-3.x, python-2.7 – Невозможный взгляд назад с обратной ссылкой

10

Из моего понимания,

<code>(.)(?<!\1)
</code>

никогда не должно совпадать. На самом деле, phppreg_replace даже отказывается компилировать это, как и ruby 'sgsub, Питонre Модуль, похоже, имеет другое мнение:

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

Результат:

<code>(x)AAAA(A)(y)BBB(B)(z)
</code>

Кто-нибудь может дать разумное объяснение этому поведению?

Update

Такое поведение представляетсяограничение вre модуль. Альтернативаregex Кажется, модуль правильно обрабатывает группы в утверждениях:

<code>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)
</code>

Обратите внимание, что в отличие отpcre, regex также позволяет смотреть за переменной ширины:

<code>print (regex.sub(r'(.)(?<![A-Z]+)', r'(\g<0>)', test))
## (x)AAAAA(y)BBBB(z)
</code>

В конце концов,regex будет включен в стандартную библиотеку, как указано вОПТОСОЗ 411.

Это соответствует, как если бы вы использовали(.)(?!\1). FakeRainBrigand

Ваш Ответ

1   ответ
5

как я узнал из обращения в службу поддержки Microsoft) в Pythonre модуль.

Я предполагаю, что это связано с тем фактом, что 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>

Поэтому лучше не использовать обратные ссылки в утверждениях в Python. Позитивный взгляд позади не намного лучше (он также соответствует здесь, как если бы это был позитивный взгляд):

>>> 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
Python, по-видимому, не единственный язык, у которого есть проблемы с обратными ссылками в утверждениях:stackoverflow.com/questions/2734977/…
Спасибо, это подтверждает мои чувства об этой ошибке. georg

Похожие вопросы