. - любой символ, кроме символа новой строки^ - начало строки$ - конец строки[abc] - любой символ в скобках[^abc] - любой символ, кроме тех, что в скобкахa|b - элемент a или b(regex) - выражение рассматривается как один элемент. Кроме того, подстрока, которая совпала с выражением, запоминается.Точка обозначает любой символ.
Чаще всего, точка используется с символами повторения + и *, чтобы указать, что между определенными выражениями могут находиться любые символы.
Например, с помощью выражения Interface.+Port ID.+ можно описать строку с интерфейсами в выводе sh cdp neighbors detail:
In [1]: cdp = ''' ...: SW1#show cdp neighbors detail ...: ------------------------- ...: Device ID: SW2 ...: Entry address(es): ...: IP address: 10.1.1.2 ...: Platform: cisco WS-C2960-8TC-L, Capabilities: Switch IGMP ...: Interface: GigabitEthernet1/0/16, Port ID (outgoing port): GigabitEthernet0/1 ...: Holdtime : 164 sec ...: ''' In [2]: re.search('Interface.+Port ID.+', cdp).group() Out[2]: 'Interface: GigabitEthernet1/0/16, Port ID (outgoing port): GigabitEthernet0/1' В результат попала только одна строка, так как точка обозначает любой символ, кроме символа перевода строки. Кроме того, символы повторения + и * по умолчанию захватывают максимально длинную строку. Этот аспект рассматривается в подразделе "Жадность символов повторения".
^Символ ^ означает начало строки. Выражению ^\d+ соответствует подстрока:
In [3]: line = "100 aa12.35fe.a5d3 FastEthernet0/1" In [4]: re.search('^\d+', line).group() Out[4]: '100' Символы с начала строки и до решетки (включая решетку):
In [5]: prompt = 'SW1#show cdp neighbors detail' In [6]: re.search('^.+#', prompt).group() Out[6]: 'SW1#' $Символ $ обозначает конец строки.
Выражение \S+$ описывает любые символы, кроме whitespace в конце строки:
In [7]: line = "100 aa12.35fe.a5d3 FastEthernet0/1" In [8]: re.search('\S+$', line).group() Out[8]: 'FastEthernet0/1' []Символы, которые перечислены в квадратных скобках, означают, что любой из этих символов будет совпадением. Таким образом можно описывать разные регистры:
In [9]: line = "100 aa12.35fe.a5d3 FastEthernet0/1" In [10]: re.search('[Ff]ast', line).group() Out[10]: 'Fast' In [11]: re.search('[Ff]ast[Ee]thernet', line).group() Out[11]: 'FastEthernet' С помощью квадратных скобок можно указать, какие символы могут встречаться на конкретной позиции. Например, выражение ^.+[>#] описывает символы с начала строки и до решетки или знака больше (включая их). С помощью такого выражения можно получить имя устройства:
In [12]: commands = ['SW1#show cdp neighbors detail', ...: 'SW1>sh ip int br', ...: 'r1-london-core# sh ip route'] ...: In [13]: for line in commands: ...: match = re.search('^.+[>#]', line) ...: if match: ...: print(match.group()) ...: SW1# SW1> r1-london-core# В квадратных скобках можно указывать диапазоны символов. Например, таким образом можно указать, что нас интересует любая цифра от 0 до 9:
In [14]: line = "100 aa12.35fe.a5d3 FastEthernet0/1" In [15]: re.search('[0-9]+', line).group() Out[15]: '100' Аналогичным образом можно указать буквы:
In [16]: line = "100 aa12.35fe.a5d3 FastEthernet0/1" In [17]: re.search('[a-z]+', line).group() Out[17]: 'aa' In [18]: re.search('[A-Z]+', line).group() Out[18]: 'F' В квадратных скобках можно указывать несколько диапазонов:
In [19]: line = "100 aa12.35fe.a5d3 FastEthernet0/1" In [20]: re.search('[a-f0-9]+\.[a-f0-9]+\.[a-f0-9]+', line).group() Out[20]: 'aa12.35fe.a5d3' Выражение [a-f0-9]+\.[a-f0-9]+\.[a-f0-9]+ описывает три группы символов, разделенных точкой. Символами в каждой группе могут быть буквы a-f или цифры 0-9. Это выражение описывает MAC-адрес.
Еще одна особенность квадратных скобок - специальные символы внутри квадратных скобок теряют свое специальное значение и обозначают просто символ. Например, точка внутри квадратных скобок будет обозначать точку, а не любой символ.
Выражение [a-f0-9]+[./][a-f0-9]+ описывает три группы символов:
Для строки line совпадением будет такая подстрока:
In [21]: line = "100 aa12.35fe.a5d3 FastEthernet0/1" In [22]: re.search('[a-f0-9]+[./][a-f0-9]+', line).group() Out[22]: 'aa12.35fe' Если после открывающейся квадратной скобки указан символ ^, совпадением будет любой символ, кроме указанных в скобках:
In [23]: line = 'FastEthernet0/0 15.0.15.1 YES manual up up' In [24]: re.search('[^a-zA-Z]+', line).group() Out[24]: '0/0 15.0.15.1 ' В данном случае выражение описывает все, кроме букв.
|Вертикальная черта работает как 'или':
In [25]: line = "100 aa12.35fe.a5d3 FastEthernet0/1" In [26]: re.search('Fast|0/1', line).group() Out[26]: 'Fast' Обратите внимание на то, как срабатывает | - Fast и 0/1 воспринимаются как целое выражение. То есть, в итоге выражение означает, что мы ищем Fast или 0/1, а не то, что мы ищем Fas, затем t или 0 и 0/1.
()Скобки используются для группировки выражений. Как и в математических выражениях, с помощью скобок можно указать, к каким элементам применяется операция.
Например, выражение [0-9]([a-f]|[0-9])[0-9] описывает три символа: цифра, потом буква или цифра и цифра:
In [27]: line = "100 aa12.35fe.a5d3 FastEthernet0/1" In [28]: re.search('[0-9]([a-f]|[0-9])[0-9]', line).group() Out[28]: '100' Скобки позволяют указывать, какое выражение является одним целым. Это особенно полезно при использовании символов повторения:
In [29]: line = 'FastEthernet0/0 15.0.15.1 YES manual up up' In [30]: re.search('([0-9]+\.)+[0-9]+', line).group() Out[30]: '15.0.15.1' Скобки позволяют не только группировать выражения. Строка, которые совпала с выражением в скобках, запоминается. Ее можно получить отдельно с помощью специальных методов groups и group(n). Это рассматривается в подразделе "Группировка выражений".