摘要
上一章节中相信大家已经对正则表达式有了基本的概念,正如我之前提到的,单纯看完知识点的介绍只能算作“记忆”,如果没有实践,就算把正则表达式全部的规则都背会了,也不能算作“学会”。今天这一章节我会带领大家实践一下如何针对实际的文本编写正则表达式。
但为什么标题是“文本解析-TextFSM”呢,因为有很多朋友一开始就想从TextFSM上手,但TextFSM究竟比正则强在哪儿?TextFSM所遵循的状态转移和匹配机制究竟是如何产生又是如何运用的?
在我带领大家实践正则表达式的过程中,大家会发现如此灵活的正则匹配的短板在哪里?而这些短板恰恰就是催生TextFSM的重要因素。
简单文本匹配
我们以Cisco设备上执行“show clock”的输出为原始文本,由于输出文本足够简单,非常适合作为第一个例子来讲解,输出如下:
18:42:41.321 CST Sun Jan 1 2023
现在想根据上述输出内容匹配几个关键信息,分别是:时间、时区、月份、日、年。
通过正则表达式来匹配的话会有好几种方式,我这里提供一个示例如下:
import re
stdout = "18:42:41.321 CST Sun Jan 1 2023"
# 括号表示获取匹配,最终会将括号内结果返回
regexp = r'(..:..:..\....) (\w+) \w+ (\w+) (\d+) (\d+)'
result = re.findall(regexp, stdout)
print(result)
# 输出结果 [('18:42:41.321', 'CST', 'Jan', '1', '2023')]
对于从一串文本中想要匹配指定的几个关键信息,通过正则表达式更为方便。
但有一个非常显而易见的缺陷,那就是我们通过“获取匹配”的方式来筛选匹配关键信息,如果一串文本中的关键信息有很多个,那正则表达式就会变得非常冗长,且最终较难区分哪个匹配结果对应哪个信息。比如上面例子中想要返回可读的结构化数据通常还需要做如下处理:
res_dict = {
"time": result[0][0],
"timezone": result[0][1],
"month": result[0][2],
"day": result[0][3],
"year": result[0][4],
}
所以到目前为止,根据一个简单的示例可以延伸分析得出,我们需要一个机制能够标识匹配表达式所对应的信息字段名称;但光有这一点,还不足以让编程人员弃用表达式,因为关键信息再多也是有限的,再不济也就是多写几个下标索引罢了。
多行文本匹配
如果输出内容是多行文本时,匹配的复杂度又会有一个新的提升,比如Cisco设备执行“show version”的输出如下:
Cisco IOS Software, Catalyst 4500 L3 Switch Software (cat4500-ENTSERVICESK9-M), Version 12.2(31)SGA1, RELEASE SOFTWARE (fc3)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2007 by Cisco Systems, Inc.
Compiled Fri 26-Jan-07 14:28 by kellythw
Image text-base: 0