Регулярное выражение: возможно ли получить числа в необязательных частях одним регулярным выражением - PullRequest
0 голосов
/ 15 января 2019

У меня есть одна строка, это будет выглядеть так: 1A2B3C или 2B3C или 1A2B или 1A3C.

Строка состоит из необязательных частей сервала number + [A|B|C].

Можно ли получить числа перед каждым символом с одним регулярным выражением?

Например:

1A2B3C => (1, 2, 3)
1A3C => (1, 0, 3) There is no 'B', so gives 0 instead. 
     => Or just (1, 3) but should show that the 3 is in front of 'C'.

1 Ответ

0 голосов
/ 15 января 2019

Предположим, 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():]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...