私の理解から、
(.)(?<!\1)
一致することはありません。実際、phppreg_replace
はこれをコンパイルすることさえ拒否しており、ruby も同様gsub
です。ただし、 pythonre
モジュールには別の意見があるようです。
import re
test = 'xAAAAAyBBBBz'
print (re.sub(r'(.)(?<!\1)', r'(\g<0>)', test))
結果:
(x)AAAA(A)(y)BBB(B)(z)
誰でもこの動作について合理的な説明を提供できますか?
アップデート
この動作は、モジュールの制限のようです。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)
PEP 411で言及されているように、最終的にregex
は標準ライブラリに含まれる予定です。