![d089d926195ebf3226114ce0a80197ba.png](https://i-blog.csdnimg.cn/blog_migrate/05cbb4ab2b8e6b7a7ede422e97f08391.jpeg)
正则表达式第二部分
上一期我们分享了正则解析的OneTake方式,比如解析mac、arp等。其实我们也可以解析version、型号、系列等单个指标信息。在全文里一次查找,都不需要将文本分行切割。
今天我们分享一种解析的思路——分而治之,带大家一起边讲边写,希望大家跟着我的思路走。
这种主要是解析show interface这种配置
![49d6aae8f34cbab5ca2c7e5b5d744131.png](https://i-blog.csdnimg.cn/blog_migrate/563064a46e7ad37be897799892c920de.jpeg)
端口配置的特点是:
1、信息是按段分开的
2、每段里面含有大量的信息
3、每段信息里有些字段是一定有的,有些是可能有可能无的
我们的思路就是:
1、先找特点,将配置信息分成一段一段的文本
2、根据要取的信息特点写正则
3、去每一段文本里匹配正则提取信息,如果无则置空字段
我们开始写一段解析端口的配置。
1、首先我们先切割文本段
把每个端口的信息放到一个字符串里处理。
确定换行符是很重要的一个环节,我们用这段代码把换行符给找出来。
![a2b8ffb72ceb88af565a662c1cb01044.png](https://i-blog.csdnimg.cn/blog_migrate/2b9ef4c6080ad60e259dcd891bebe1e3.jpeg)
有时候设备的换行符是“rn”,这个里面是"n"(说实话底层我也不太清楚,但是我知道Linux和windows对于换行是有区别的,与采集的设备和被采集的设备可能都有关系。建议初期大家都去看换行是什么。后期写的代码我很少通过本地直接采集设备,而是通过一个自己封装的API去ssh到设备采集信息,所以返回的格式比较统一,但是偶尔有时候也会出现有的设备返回的是rn,有的返回的是rn,所以具体问题具体分析,同时我会在处理正则的时候全局把换行统一一下)
![f7495c00c881aa45c37d45788bf47ee6.png](https://i-blog.csdnimg.cn/blog_migrate/1662ad3b68b1b99efc60d33673066b74.jpeg)
从上面的截图我们发现,端口的信息总是端口名称 is 开头,两个换行结束,所以我们用正则去把所需要的全部端口文本先筛选出来。
![d05b0903e366e7864b4ffdd0a474ea48.png](https://i-blog.csdnimg.cn/blog_migrate/781d7fff84adbe345f03049fdb2a141b.jpeg)
这里面还是有三点要说,
“(?:一段正则|)”,两个部分说,圆括号代表的是优先级,这几个端口类型是或的关系“|”,为了防止下面这种情况我们把端口类型几个用圆括号给圈起来
![732af4b9798cdb7788414a99ae023e21.png](https://i-blog.csdnimg.cn/blog_migrate/cfc8e4efb1907f716a32975baeaf10dc.jpeg)
圆括号表示是一个整体,同时默认代表的是提取这个串。结果如果不加“?:”,我们提取的结果是端口名称,而没有提取整个端口的信息,有两种做法,一种是用“?:”代表识别正则但是不提取子串,所以findall是以整体去提出每个端口的配置信息。
第二种方式是把整个串再用圆括号圈起来,那findall会识别第一个子串和整体这个子串,返回的是tuple的列表。
![6f0c2e82311e0753cdcf664570279d17.png](https://i-blog.csdnimg.cn/blog_migrate/95f5251dcad9b8347b92566e2e54aafa.jpeg)
我不太推荐第二种方法。
然后是findall的用法,之前正则也讲过,就是返回所有匹配的数据列表,数据可能是字符串可能是tuple等。大家尽量用第一种方法,返回的就是字符串了。
还有一个点就是我用了“[sS]+?"端口开头和两个换行中间的部分,同时用的是非贪婪,这样防止它把中间其他端口贪婪的也识别了。
2、文本内编写OneTake,提取重要信息
接下来做的就很简单了,在每个提取的文本段内(字符串)提取我们想要的端口信息就可以了,你可以写正则,甚至用字符串的一些find、index等方法提取,用最省力的。这段无疑用正则一个个去解析最合适。
我们打个样,在文本内去解析端口名和状态以及端口描述,其他的大家可以自己练习以下。
先写端口的,其实刚才我们已经写好了端口的正则了
intf_name_re = re.compile(r'Ethernetd+/d+|Vland+|mgmtd+',re.I)
intf_protocol_status_re = re.compile( r'd+siss([a-zA-Z]+)',re.I)
intf_desc_re = re.compile( r'Description:([sS]+?)n',re.I)
- 端口的没什么好说的。后面加了re.I代表的是忽略大小写。
- 状态的找规律即可,前面是端口号数字空格然后是is,紧接着是空格,后面是up、down,防止以后出幺蛾子,我们用字母框都匹配。这个地方设计到数据建模问题,我们的每个字段后期一定是我们的一个数据表,数据结构,所以前期每个字段都要斟酌,比如状态是分协议状态和配置状态的。
- 描述的我们中间用空格非空格非贪婪一下匹配到换行结束,简单粗暴。
上代码和结果
![d454c4e4034c8c666e53f6d659a446f1.png](https://i-blog.csdnimg.cn/blog_migrate/e45dfb1e86dc8f29e8c5098775761323.jpeg)
可以看到拿到了端口的信息表,还有很多字段大家可以按需去添加。
有几点说明:
- 我们用了search,注意它和match的区别
- 我们取字段的时候group的一些操作
- 注意我的缩进,变量命名方式
- 我们预先赋值字段,防止到时候引用发现没有定义
以上就是今天的分享,今天的正则,我变着花的给大家写,希望尽量带入一些知识点,这些花儿也是必要的。后续还会继续分享一些TIPS。
希望大家体会我在写这个正则时候的思路,顺序。这是我们写了这么久的一个经验总结,最佳实践~可以少走一些弯路。
最后奉上今天的主体代码,希望大家点赞、分享、订阅、喜欢、在看~
下一篇文章,我打算写写非技术的,胡吹乱侃一些对NetDevOps的看法。大家在技术上有什么难题也欢迎与我分享,我也许可以提供一些思路~
同时在考虑 要不要来一个集赞写正则的活动:)
import