Ответ 1
Я думаю, что проблема может заключаться в том, что шаблон регулярного выражения соответствует одному или другому подшаблонам EN_EXTRACT_REGEX
и NUM_EXTRACT_REGEX
, но не тем и другим.
Когда re.sub()
соответствует альфа-символам в первом паттерне, он пытается заменить вторую ссылку на группу \2
, которая терпит неудачу, потому что только первая группа соответствует - нет второй группы.
Аналогично, когда сопоставляется символ цифр, нет подменю \1
, и это также не выполняется.
Вы можете видеть, что это имеет место с этим тестом в Python 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
Разница должна лежать в разных версиях движка regex для Python 2 и Python 3. К сожалению, я не могу дать окончательную причину разницы, однако есть документированное изменение в версии 3.5 для re.sub()
в отношении несогласованных групп:
Изменено в версии 3.5: Непревзойденные группы заменяются пустой строкой.
который объясняет, почему он работает в Python >= 3.5, но не в ранних версиях: несогласованные группы в основном игнорируются.
В качестве обходного пути вы можете изменить свой шаблон, чтобы обрабатывать оба совпадения как одну группу:
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))
Выход
1234 abcd a 1 b 2 c 3 aa__ bb__ 1122 cdef _**_