обработка совпадений нулевой длины изменилась в Python 3.7.Рассмотрим следующее с Python 3.6 (и предыдущий):
>>> import re
>>> print(re.sub('a*', 'x', 'bac'))
xbxcx
>>> print(re.sub('.*', 'x', 'bac'))
x
Мы получаем следующее с Python 3.7:
>>> import re
>>> print(re.sub('a*', 'x', 'bac'))
xbxxcx
>>> print(re.sub('.*', 'x', 'bac'))
xx
Я понимаю, что это стандартное поведение PCRE.Кроме того, re.finditer (), кажется, всегда обнаруживал дополнительное совпадение:
>>> for m in re.finditer('a*', 'bac'):
... print(m.start(0), m.end(0), m.group(0))
...
0 0
1 2 a
2 2
3 3
Тем не менее, мне интересно узнать поведение Python 3.6 (это для хобби-проекта, реализующего sed в python ).
Я могу прийти со следующим решением:
def sub36(regex, replacement, string):
compiled = re.compile(regex)
class Match(object):
def __init__(self):
self.prevmatch = None
def __call__(self, match):
try:
if match.group(0) == '' and self.prevmatch and match.start(0) == self.prevmatch.end(0):
return ''
else:
return re._expand(compiled, match, replacement)
finally:
self.prevmatch = match
return compiled.sub(Match(), string)
, которое дает:
>>> print(re.sub('a*', 'x', 'bac'))
xbxxcx
>>> print(sub36('a*', 'x', 'bac'))
xbxcx
>>> print(re.sub('.*', 'x', 'bac'))
xx
>>> print(sub36('.*', 'x', 'bac'))
x
Однако, это кажется очень сложным дляэти примеры.
Как правильно реализовать поведение Python 3.6 для совпадений нулевой длины с re.sub () с Python 3.7?