- ru
- Language: en
- Documentation version: latest
Группа без захвата
По умолчанию все, что попало в группу, запоминается. Это называется группа с захватом.
Иногда скобки нужны для указания части выражения, которое повторяется. И, при этом, не нужно запоминать выражение.
Например, надо получить 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('((\w{4}\.){2}\w{4}).+vlan (\d+).+port (\S+).+port (\S+)', log)
Выражение состоит из таких частей:
((\w{4}\.){2}\w{4})
- сюда попадет MAC-адрес\w{4}\.
- эта часть описывает 4 буквы или цифры и точку(\w{4}\.){2}
- тут скобки нужны, чтобы указать, что 4 буквы или цифры и точка повторяются два раза\w{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')
Второй элемент, по сути, лишний. Он попал в вывод из-за скобок в
выражении (\w{4}\.){2}
.
В этом случае нужно отключить захват в группе. Это делается добавлением
?:
после открывающейся скобки группы.
Теперь выражение выглядит так:
In [4]: match = re.search('((?:\w{4}\.){2}\w{4}).+vlan (\d+).+port (\S+).+port (\S+)', log)
И, соответственно, группы:
In [5]: match.groups()
Out[5]: ('f03a.b216.7ad7', '10', 'Gi0/5', 'Gi0/15')