路由器日志正则匹配需求:适配可变列宽的表头文本块提取
路由器日志文本提取正则优化方案
问题背景
之前使用的正则依赖固定列宽的表头,仅能适配40台路由器的日志提取:
regex_to_find = "(?s)(?<=VPN IF NAME ID VIRTUAL IP VIRTUAL MAC PRIORITY PRIORITY STATE STATE TIMER TIMER LAST STATE CHANGE TIME LIST STATE)(.*?)(?=" + routername + ")" regex_result = re.search(regex_to_find, filecontent)
但新增650台路由器的日志后,发现表头列宽随字段动态变化(如VPN IF_NAME与VPN IF_NAME的空格数不同),原正则失效。
需求
匹配以VPN开头、包含IF_NAME、以STATE结尾的表头行作为起始,到**路由器名称提示符(如PZMO120#)**结束的完整文本块。
解决方案
适配动态表头的正则表达式
(?s)(?<=^VPN\s+.*IF_NAME\s+.*STATE$)(.*?)(?=^\w+#)
正则说明
(?s):启用单行模式,让.可以匹配换行符,支持跨多行匹配(?<=^VPN\s+.*IF_NAME\s+.*STATE$):正向回溯断言,精准匹配目标表头行:^/$:限定为整行匹配,避免匹配行内片段VPN\s+:匹配行首的VPN及后续任意数量空格.*IF_NAME\s+:匹配包含IF_NAME的任意内容及后续空格.*STATE$:匹配行尾的STATE
(.*?):非贪婪匹配表头行之后的所有内容(包括分隔线、数据行)(?=^\w+#):正向前瞻断言,匹配行首的路由器提示符(如PZMO120#),作为匹配结束的边界
Python代码实现
import re # 日志内容示例 filecontent = """ PZMO120# PZMO120# show interface description IF IF IF IPV6 AF ADMIN OPER TRACKER ADMIN VPN INTERFACE TYPE IP ADDRESS STATUS STATUS STATUS DESC STATUS ------------------------------------------------------------------------------------------------------------------------------------------------------------ 0 ge0/0 ipv4 xx.yy.zz.r/pp Up Up Up ORCH=NETWORK - To INTERNET Up 0 ge0/1 ipv4 - Up Up NA ORCH=NETWORK - TLOC Extension - B2B between Primary vEdge & Secondary vEdge Up 0 ge0/2 ipv4 - Down Down NA None Up 65530 ge0/3 ipv4 - Up Up NA ORCH=NETWORK - CUSTOMER LAN - Service VPN physical interface Up PZMO120# PZMO120# PZMO120# show vrrp PRIMARY TRACK PREFIX GROUP REAL VRRP OMP ADVERTISEMENT DOWN PREFIX LIST VPN IF NAME ID VIRTUAL IP VIRTUAL MAC PRIORITY PRIORITY STATE STATE TIMER TIMER LAST STATE CHANGE TIME LIST STATE -------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 ge0/3.510 10 zz.zz.zz.x 00:00:??:00:01:0a 150 150 primary up 1 3 2022-12-06T19:32:06+00:00 - - 2 ge0/3.511 11 yy.yy.yy.r 00:00:??:00:01:0b 150 150 primary up 1 3 2022-12-06T19:32:06+00:00 - - PZMO120# PZMO120# show run vpn 1 """ # 适配动态表头的正则 regex_to_find = r"(?s)(?<=^VPN\s+.*IF_NAME\s+.*STATE$)(.*?)(?=^\w+#)" # 启用多行模式确保^/$匹配行首行尾 regex_result = re.search(regex_to_find, filecontent, re.MULTILINE) if regex_result: print("提取到的日志块:") print(regex_result.group().strip())
匹配效果
上述代码会精准提取VRRP命令对应的日志块:
-------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 ge0/3.510 10 zz.zz.zz.x 00:00:??:00:01:0a 150 150 primary up 1 3 2022-12-06T19:32:06+00:00 - - 2 ge0/3.511 11 yy.yy.yy.r 00:00:??:00:01:0b 150 150 primary up 1 3 2022-12-06T19:32:06+00:00 - -
内容的提问来源于stack exchange,提问作者Harry Leboeuf
相关产品推荐
相关产品推荐

