По умолчанию все, что попало в группу, запоминается. Это называется группа с захватом.
Но иногда скобки нужны для указания части выражения, которое повторяется. И, при этом, не нужно запоминать выражение.
Например, надо получить MAC-адрес, VLAN и порты из такого лог-сообщения:
In [1]: log = 'Jun 3 14:39:05.941: %SW_MATM-4-MACFLAP_NOTIF: Host f03a.b216.7ad7 in vlan 10 is flapping between port Gi0/5 and port Gi0/15'
Регулярное выражение, которое описывает нужные подстроки:
In [2]: match = re.search('(([0-9a-fA-F]{4}\.){2}[0-9a-fA-F]{4}).+vlan (\d+).+port (\S+).+port (\S+)', log)
Выражение состоит из таких частей:
(([0-9a-fA-F]{4}\.){2}[0-9a-fA-F]{4})
- сюда попадет MAC-адрес[0-9a-fA-F]{4}\.
- эта часть описывает 4 буквы или цифры и точку([0-9a-fA-F]{4}\.){2}
- тут скобки нужны, чтобы указать, что 4 буквы или цифры и точка повторяются два раза[0-9a-fA-F]{4}
- затем 4 буквы или цифры.+vlan (\d+)
- в группу попадет номер VLAN .+port (\S+)
- первый интерфейс.+port (\S+)
- второй интерфейсМетод groups вернет такой результат:
In [3]: match.groups() Out[3]: ('f03a.b216.7ad7', 'b216.', '10', 'Gi0/5', 'Gi0/15')
Второй элемент, по сути, лишний. Он попал в вывод из-за скобок в выражении ([0-9a-fA-F]{4}\.){2}
.
В этом случае нужно отключить захват в группе. Это делается добавлением ?:
после открывающейся скобки группы.
Теперь выражение выглядит так:
In [4]: match = re.search('((?:[0-9a-fA-F]{4}\.){2}[0-9a-fA-F]{4}).+vlan (\d+).+port (\S+).+port (\S+)', log)
И, соответственно, группы:
In [5]: match.groups() Out[5]: ('f03a.b216.7ad7', '10', 'Gi0/5', 'Gi0/15')