С моей точки зрения,
(.)(?<!\1)
никогда не должно совпадать. На самом деле, php preg_replace
даже отказывается компилировать это, а также ruby gsub
. У модуля python re
, похоже, есть другое мнение:
import re
test = 'xAAAAAyBBBBz'
print (re.sub(r'(.)(?<!\1)', r'(\g<0>)', test))
Результат:
(x)AAAA(A)(y)BBB(B)(z)
Может ли кто-нибудь дать разумное объяснение этому поведению?
Update
Это поведение выглядит как ограничение в модуле re
. Альтернативный regex
, похоже, правильно обрабатывает группы в утверждениях:
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)
Обратите внимание, что в отличие от pcre
, regex
также позволяет искать переменные ширины:
print (regex.sub(r'(.)(?<![A-Z]+)', r'(\g<0>)', test))
## (x)AAAAA(y)BBBB(z)
В конце концов, regex
будет включен в стандартную библиотеку, как указано в PEP 411.