TextFSM解析traceroute:函数内变量调用返回空列表求助
问题:函数内存储traceroute输出时TextFSM解析返回空列表
问题现象
无函数结构的代码中,TextFSM可正常解析traceroute输出;但将逻辑封装到函数后,用变量存储多行字符串形式的traceroute输出时,解析结果返回空列表(退出码为0);直接传入无缩进的换行字符串则解析正常。
测试环境:Windows 11笔记本/Windows Server 2016服务器,Python 3.6、3.8、3.11版本,Idle、PyCharm、Visual Code等IDE测试结果一致。
正常运行的无函数代码
import textfsm # 加载TextFSM模板 with open("templates/traceroute_template.textfsm") as template_file: template = textfsm.TextFSM(template_file) # 从变量读取traceroute输出 trace_output = """ 1 1.1.1.1 0.735 ms 2 2.2.2.2 0.589 ms 3 3.3.3.3 1.122 ms """ # 解析traceroute输出 parsed_data = template.ParseText(trace_output) print(parsed_data)
输出结果符合预期:
[['1', '1.1.1.1'], ['2', '2.2.2.2'], ['3', '3.3.3.3']] Process finished with exit code 0
函数内返回空列表的代码
import textfsm def get_trace(): # 加载TextFSM模板 with open("templates/traceroute_template.textfsm") as template_file: template = textfsm.TextFSM(template_file) # 从变量读取traceroute输出 trace_output = """ 1 1.1.1.1 0.735 ms 2 2.2.2.2 0.589 ms 3 3.3.3.3 1.122 ms """ # 解析traceroute输出 parsed_data = template.ParseText(trace_output) print(parsed_data) get_trace()
输出结果为空列表:
[] Process finished with exit code 0
函数内直接传字符串正常的代码
import textfsm def get_trace(): # 加载TextFSM模板 with open("templates/traceroute_template.textfsm") as template_file: template = textfsm.TextFSM(template_file) # 直接传入无缩进的换行字符串 parsed_data = template.ParseText("""1 1.1.1.1 0.735 ms\r2 2.2.2.2 0.589 ms\r3 3.3.3.3 1.122 ms""") print(parsed_data) get_trace()
输出结果符合预期:
[['1', '1.1.1.1'], ['2', '2.2.2.2'], ['3', '3.3.3.3']] Process finished with exit code 0
使用的TextFSM模板
Value Hop (\d+) Value IP (\S+) Start ^${Hop}\s+${IP} -> Record
原因分析
函数内的多行字符串包含前导空格,而TextFSM模板中的正则规则^${Hop}\s+${IP}要求行首必须是数字(Hop字段),前导空格导致正则无法匹配任何行,因此返回空列表。无函数代码中的多行字符串没有前导空格,所以能正常匹配。
解决方法
方法1:去除多行字符串的前导空格
修改函数内的trace_output,让每行开头直接是数字:
trace_output = """ 1 1.1.1.1 0.735 ms 2 2.2.2.2 0.589 ms 3 3.3.3.3 1.122 ms """
方法2:修改TextFSM模板,允许行首有空白字符
调整正则规则,允许行首出现任意数量的空白字符:
Value Hop (\d+) Value IP (\S+) Start ^\s*${Hop}\s+${IP} -> Record
方法3:预处理字符串,去除每行前导空白
对trace_output进行预处理,自动去除每行的前导空格:
trace_output = '\n'.join(line.strip() for line in trace_output.splitlines())
内容的提问来源于stack exchange,提问作者robmo
相关产品推荐
相关产品推荐

