Myślę, że problemem może być to, że wzór regex dopasowuje jeden lub drugiego z podwzorów EN_EXTRACT_REGEX
i NUM_EXTRACT_REGEX
, ale nie jednocześnie.
Gdy re.sub()
pasuje do znaków alfa w pierwszym wzorze, próbuje zastąpić odwołanie do drugiej grupy przez \2
, które nie działa, ponieważ tylko pierwsza grupa jest zgodna - nie ma drugiej grupy.
Podobnie, gdy dopasowany jest wzór cyfry, grupa \1
nie jest substytutem, a więc również się nie powiedzie.
Widać, że to jest w przypadku tego testu w Pythonie 2:
>>> re.sub(AGGR_REGEX, r' \1', 'abcd') # reference first pattern
abcd
>>> re.sub(AGGR_REGEX, r' \2', 'abcd') # reference second pattern
Traceback (most recent call last):
....
sre_constants.error: unmatched group
Różnica musi znajdować się w różnych wersjach silnika regex dla Python 2 i Python 3. Niestety nie mogę zapewnić ostateczne powodem różnicy, jednak nie jest to udokumentowane zmiana w wersji 3.5 dla re.sub()
dotyczące grup niedopasowanych:
Zmieniono w wersji 3.5: grupy Niezrównane są zastąpione pustym ciągiem.
wyjaśnia, dlaczego działa w języku Python> = 3.5, ale nie we wcześniejszych wersjach: niedopasowane grupy są zasadniczo ignorowane.
Jako obejście można zmienić wzór obsługiwać oba mecze jako jedna grupa:
import re
EN_EXTRACT_REGEX = '[a-zA-Z]+'
NUM_EXTRACT_REGEX = '[0-9]+'
AGGR_REGEX = '(' + EN_EXTRACT_REGEX + '|' + NUM_EXTRACT_REGEX + ')'
# ([a-zA-Z]+|[0-9]+)
for s in '', '1234', 'abcd', 'a1b2c3', 'aa__bb__1122cdef', '_**_':
print(re.sub(AGGR_REGEX, r' \1', s))
Output
1234
abcd
a 1 b 2 c 3
aa__ bb__ 1122 cdef
_**_
Dzięki, to działa dobrze w obu wersjach. :) –