Предположим, Python из-за вашей нотации кортежей и потому, что я чувствую, что хочу использовать.
Если разрешены только буквы A
, B
и C
, вы можете сделать это с дополнительным шагом обработки:
pattern = re.compile(r'(?:(\d+)A)(?:(\d+)B)?(?:(\d+)C)?')
match = pattern.fullmatch(some_string)
if match:
result = tuple(int(g) for g in match.groups('0'))
else:
raise ValueError('Bad input string')
Каждый параметр окружен не захватывающей группой (?:...)
, поэтому все рассматривается как единое целое. Внутри устройства есть группа захвата (\d+)
для захвата номера и незафиксированный символ.
Метод Matcher.groups
возвращает кортеж всех групп в регулярном выражении с несопоставленными группами, установленными в '0'. Затем генератор преобразуется в int
для вас. Вы можете использовать tuple(map(int, match.groups('0')))
.
Вы также можете использовать словарь для хранения чисел, набираемых по буквам:
pattern = re.compile(r'(?:(?P<A>\d+)A)(?:(?P<B>\d+)B)?(?:(?P<C>\d+)C)?')
match = pattern.fullmatch(some_string)
if match:
result = {k: int(v) for k, v in match.groupdict('0').items()}
else:
raise ValueError('Bad input string')
Matcher.groupdict
аналогично groups
, за исключением того, что он возвращает словарь именованных групп: группы захвата отмечены (?P<NAME>...)
.
Наконец, если вы не возражаете против использования словаря, вы можете адаптировать этот подход для анализа любого количества групп с произвольными символами:
pattern = re.compile(r'(\d+)([A-Z])')
result = {}
while some_string:
match = pattern.match(some_string)
if not match:
raise ValueError('Bad input string')
result[match.group(2)] = int(match.group(1))
some_string = some_string[match.end():]