Python regex named group

Группировка выражений#

Группировка выражений указывает, что последовательность символов надо рассматривать как одно целое. Однако это не единственное преимущество группировки.

Кроме этого, с помощью групп можно получать только определенную часть строки, которая была описана выражением. Это очень полезно в ситуациях, когда надо описать строку достаточно подробно, чтобы отобрать нужные строки, но в то же время из самой строки надо получить только определенное значение.

Например, из log-файла надо отобрать строки, в которых встречается «%SW_MATM-4-MACFLAP_NOTIF», а затем из каждой такой строки получить MAC-адрес, VLAN и интерфейсы. В этом случае регулярное выражение просто должно описывать строку, а все части строки, которые надо получить в результате, просто заключаются в скобки.

В Python есть два варианта использования групп:

Нумерованные группы#

Группа определяется помещением выражения в круглые скобки () .

Внутри выражения группы нумеруются слева направо, начиная с 1. Затем к группам можно обращаться по номерам и получать текст, который соответствует выражению в группе.

Пример использования групп:

In [8]: line = "FastEthernet0/1 10.0.12.1 YES manual up up" In [9]: match = re.search(r'(\S+)\s+([\w.]+)\s+.*', line) 

В данном примере указаны две группы:

  • первая группа — любые символы, кроме пробельных
  • вторая группа — любая буква или цифра (символ \w ) или точка

Вторую группу можно было описать так же, как и первую. Другой вариант сделан просто для примера

Теперь можно обращаться к группам по номеру. Группа 0 — это строка, которая соответствует всему шаблону:

In [10]: match.group(0) Out[10]: 'FastEthernet0/1 10.0.12.1 YES manual up up' In [11]: match.group(1) Out[11]: 'FastEthernet0/1' In [12]: match.group(2) Out[12]: '10.0.12.1' 

При необходимости можно перечислить несколько номеров групп:

In [13]: match.group(1, 2) Out[13]: ('FastEthernet0/1', '10.0.12.1') In [14]: match.group(2, 1, 2) Out[14]: ('10.0.12.1', 'FastEthernet0/1', '10.0.12.1') 

Начиная с версии Python 3.6, к группам можно обращаться таким образом:

In [15]: match[0] Out[15]: 'FastEthernet0/1 10.0.12.1 YES manual up up' In [16]: match[1] Out[16]: 'FastEthernet0/1' In [17]: match[2] Out[17]: '10.0.12.1' 

Для вывода всех подстрок, которые соответствуют указанным группам, используется метод groups:

In [18]: match.groups() Out[18]: ('FastEthernet0/1', '10.0.12.1') 

Именованные группы#

Когда выражение сложное, не очень удобно определять номер группы. Плюс, при дополнении выражения, может получиться так, что порядок групп изменился, и придется изменить и код, который ссылается на группы.

Именованные группы позволяют задавать группе имя.

Синтаксис именованной группы (?Pregex) :

In [19]: line = "FastEthernet0/1 10.0.12.1 YES manual up up" In [20]: match = re.search(r'(?P\S+)\s+(?P[\d.]+)\s+', line) 

Теперь к этим группам можно обращаться по имени:

In [21]: match.group('intf') Out[21]: 'FastEthernet0/1' In [22]: match.group('address') Out[22]: '10.0.12.1' 

Также очень полезно то, что с помощью метода groupdict(), можно получить словарь, где ключи — имена групп, а значения — подстроки, которые им соответствуют:

In [23]: match.groupdict() Out[23]: 'address': '10.0.12.1', 'intf': 'FastEthernet0/1'> 

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

In [24]: match = re.search(r'(?P\S+)\s+(?P[\d\.]+)\s+\w+\s+\w+\s+(?Pup|down)\s+(?Pup|down)', line) In [25]: match.groupdict() Out[25]: 'address': '10.0.12.1', 'intf': 'FastEthernet0/1', 'protocol': 'up', 'status': 'up'> 

Источник

Читайте также:  Use php in console
Оцените статью