Книга: PyNEng
Назад: Группировка выражений
Дальше: Повторение захваченного результата

Группа без захвата

Группа без захвата

По умолчанию все, что попало в группу, запоминается. Это называется группа с захватом.

Но иногда скобки нужны для указания части выражения, которое повторяется. И, при этом, не нужно запоминать выражение.

Например, надо получить 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') 
Назад: Группировка выражений
Дальше: Повторение захваченного результата