网络工程师Python正则表达式(re实验2,Search函数,处理单行文本)
哈喽,大家好,我又来了。上次实验我们主要对python正则表达式re模块做了个入门串讲,重点介绍了Match对象。这次实验我们继续推进,学习Search函数。
本文部分参考知乎专栏 @弈心 《 网路行者 》实验思想,推荐移步阅读。
本文部分参考书籍《 Python for network engineers 》,纯英文,推荐移步阅读。
本专栏简介及目录入口,如果您不知道从何读起,建议从这篇《目录》开始,连接如下:
Search函数概述
search()函数的主要功能:
- 在字符串中,查找与模板规则匹配的子字符串。
- 如果找到子字符串,则返回 Match 对象。
- 如果未能找到,则返回 None。
如果你只想在字符串中找一个匹配项,而非多个(规则匹配字符串全部或一部分),那使用search()函数就再合适不过了。
实验目的
(1)正则表达式匹配单行日志。
(2)在(1)的基础上,读取日志文件,逐行匹配。
实验过程
尽量切近上篇实验,我们还用search()来解析日志文件。log.txt包含了多条信息,这些信息表明相同的MAC在不同的接口上反复学习,即“MAC地址漂移”。产生“MAC地址漂移”日志的原因挺多了,比如网络中产生了环路。
log.txt的内容:
Sep 26 2021 23:11:02-08:00 Layer3Switch-1 L2IFPPI/4/MFLPVLANALARM:OID 1.3.6.1.4.1.2011.5.25.160.3.7 MAC move detected, VlanId = 54, MacAddress = 0000-5e00-0136, Original-Port = GE0/0/1, Flapping port = GE0/0/2. Please check the network accessed to flapping port.
Sep 26 2021 23:11:08-08:00 Layer3Switch-1 L2IFPPI/4/MFLPVLANALARM:OID 1.3.6.1.4.1.2011.5.25.160.3.7 MAC move detected, VlanId = 54, MacAddress = 0000-5e00-0136, Original-Port = GE0/0/1, Flapping port = GE0/0/2. Please check the network accessed to flapping port.
Sep 26 2021 23:11:10-08:00 Layer3Switch-1 L2IFPPI/4/MFLPVLANALARM:OID 1.3.6.1.4.1.2011.5.25.160.3.7 MAC move detected, VlanId = 54, MacAddress = 0000-5e00-0136, Original-Port = GE0/0/2, Flapping port = GE0/0/3. Please check the network accessed to flapping port.
Sep 26 2021 23:11:15-08:00 Layer3Switch-1 L2IFPPI/4/MFLPVLANALARM:OID 1.3.6.1.4.1.2011.5.25.160.3.7 MAC move detected, VlanId = 54, MacAddress = 0000-5e00-0136, Original-Port = GE0/0/3, Flapping port = GE0/0/1. Please check the network accessed to flapping port.
网络中发生了MAC漂移,即MAC地址可以在不同的接口上来回跳转。这种情况下,日志分析可以从“确定MAC跳转的具体接口”的角度切入。
第 1 步,正则处理一行日志
我们尝试写一个正则表达式,然后用log.txt中的一行来检查。 我写正则表达式有个习惯,就是在一截待匹配的文本上直接改,该替换成\S+、\d+等就直接替换,而非从空白来写。
>>> log = 'Sep 26 2021 23:11:02-08:00 Layer3Switch-1 L2IFPPI/4/MFLPVLANALARM:OID 1.3.6.1.4.1.2011.5.25.160.3.7 MAC move detected, VlanId = 54, MacAddress = 0000-5e00-0136, Original-Port = GE0/0/1, Flapping port = GE0/0/2. Please check the network accessed to flapping port.'
>>> match = re.search(r'VlanId = (\d+), MacAddress = \S+, Original-Port = (\S+), Flapping port = (\S+)\.',log)
>>> match.groups()
('54', 'GE0/0/1', 'GE0/0/2')
我们截图一下,清晰一点。
我们再把规则格式调整一下,更加直观一点。(但其实意义不是很大我觉得~)
>>> log
'Sep 26 2021 23:11:02-08:00 Layer3Switch-1 L2IFPPI/4/MFLPVLANALARM:OID 1.3.6.1.4.1.2011.5.25.160.3.7 MAC move detected, VlanId = 54, MacAddress = 0000-5e00-0136, Original-Port = GE0/0/1, Flapping port = GE0/0/2. Please check the network accessed to flapping port.'
>>> match = re.search(r'VlanId = (\d+), '
r'MacAddress = \S+, '
r'Original-Port = (\S+), '
r'Flapping port = (\S+)\.',log)
>>> match.groups()
('54', 'GE0/0/1', 'GE0/0/2')
(\d+) | 提取vlan号 |
\S+ | 仅匹配mac地址,不不提取 |
(\S+) | 提取mac漂移的端口 |
我们在上表再次梳理下,反复啰嗦的目的在于让您理解加括号和不加括号的差异。如果加括号了,即分组,也叫子组,匹配完成后,我们就可以配合groups()、group()进行提取。
第 2 步,正则逐行处理日志
我们来做一个脚本,逐行处理log.txt,这个过程用上述的正则表达式进行匹配,收集需要的信息。从文本中我们还看到有些漂移端口是重复的,此时我们装入集合set进行去重。(装逼的说法叫“洗数据”或者“把数据洗一下”。哈)
我们把log.txt、lab2.py(命名可根据自己喜好)放入同一文件夹中。lab2.py的脚本如下:
import re
regex = (r'VlanId = (\d+), '
r'MacAddress = \S+, '
r'Original-Port = (\S+), '
r'Flapping port = (\S+)\.')
ports = set()
with open('log.txt') as f:
for line in f:
match = re.search(regex, line)