python - 需要帮助解析 Cisco 输出

标签 python regex parsing ciscoconfparse

我在尝试解析路由器的 mrib 表时遇到一些问题。我已经能够解析其中的一些内容,但有问题。例如我有以下输出:

(192.168.1.1,232.0.6.8) RPF nbr: 55.44.23.1 Flags: RPF
  Up: 4w1d
  Incoming Interface List
    TenGigE0/0/0/1 Flags: A, Up: 4w1d
  Outgoing Interface List
    TenGigE0/0/0/10 Flags: A, Up: 4w1d

(192.168.55.3,232.0.10.69) RPF nbr: 66.76.44.130 Flags: RPF
  Up: 4w1d
  Incoming Interface List
    TenGigE0/0/0/0 Flags: A, Up: 4w1d
    TenGigE0/1/0/0 Flags: A, Up: 4w1d
    TenGigE0/2/0/0 Flags: A, Up: 4w1d
  Outgoing Interface List
    TenGigE0/0/0/10 Flags: A, Up: 4w1d
    TenGigE0/3/0/0 Flags: A, Up: 4w1d
    TenGigE0/4/0/0 Flags: A, Up: 4w1d

我正在尝试使用上述输出构建数据结构。为了清楚起见,我希望它看起来像这样:

{'192.168.1.1,232.0.6.8': {'incoming': ['TenGigE0/0/0/1'],
                           'outgoing': ['TenGigE0/0/0/10']}}

上面的内容听起来很简单。我遇到的主要问题之一是第二个 block 。我正在尝试找到一种方法来迭代传入和传出接口(interface)之后的接口(interface)。

不一定需要代码,但是做这样的事情最好的方法是什么?

最佳答案

好吧,如果您能够使用更新的 regex module在 Python 中,您可以定义子模式并使用以下方法:

  1. 在开头定义 IP 地址的子模式
  2. ...以及传入和传出接口(interface)
  3. 单独解析接口(interface)
  4. 参见a demo on regex101.com .


定义子模式

定义传入传出接口(interface)字符串、IP地址和结尾的子模式。

(?(DEFINE)
    (?<ips>[^()]+)
    (?<incoming>Incoming\ Interface \ List)
    (?<outgoing>Outgoing\ Interface \ List)
    (?<end>^$|\Z)
)

将正则表达式放在一起

将 IP 部分锚定到行的开头,并对传入/传出部分使用带有负向前瞻脾气暴躁标记。

    ^\((?P<ip>(?&ips))\)
    (?:(?!(?&incoming))[\s\S]+?)
    (?&incoming)[\r\n]
    (?P<in>(?!(?&outgoing))[\s\S]+?) # tempered greedy token
    (?&outgoing)[\r\n]
    (?P<out>(?!^$)[\s\S]+?)
    (?&end)

解析传入/传出部分

由于您只需要接口(interface)类型/名称,因此您可以简单地提出:

TenGig\S+ # TenGig, followed by anything NOT a whitespace

提示

您实际上并不需要定义子模式,但是您需要多次重复自己(因为否定前瞻)。因此,如果您需要坚持使用原始的 re 模块,您也可以很好地使用它。

粘在一起

所有内容都用代码粘合在一起,这将是:

import regex as re

string = """
(192.168.1.1,232.0.6.8) RPF nbr: 55.44.23.1 Flags: RPF
  Up: 4w1d
  Incoming Interface List
    TenGigE0/0/0/1 Flags: A, Up: 4w1d
  Outgoing Interface List
    TenGigE0/0/0/10 Flags: A, Up: 4w1d

(192.168.55.3,232.0.10.69) RPF nbr: 66.76.44.130 Flags: RPF
  Up: 4w1d
  Incoming Interface List
    TenGigE0/0/0/0 Flags: A, Up: 4w1d
    TenGigE0/1/0/0 Flags: A, Up: 4w1d
    TenGigE0/2/0/0 Flags: A, Up: 4w1d
  Outgoing Interface List
    TenGigE0/0/0/10 Flags: A, Up: 4w1d
    TenGigE0/3/0/0 Flags: A, Up: 4w1d
    TenGigE0/4/0/0 Flags: A, Up: 4w1d
"""

rx = re.compile(r"""
            (?(DEFINE)
                (?<ips>[^()]+)
                (?<incoming>Incoming\ Interface \ List)
                (?<outgoing>Outgoing\ Interface \ List)
                (?<end>^$|\Z)
            )
            ^\((?P<ip>(?&ips))\)
            (?:(?!(?&incoming))[\s\S]+?)
            (?&incoming)[\r\n]
            (?P<in>(?!(?&outgoing))[\s\S]+?)
            (?&outgoing)[\r\n]
            (?P<out>(?!^$)[\s\S]+?)
            (?&end)
""", re.MULTILINE|re.VERBOSE)

rxiface = re.compile(r'TenGig\S+')

result = dict()
for match in rx.finditer(string):
    key = match.group('ip')
    incoming = rxiface.findall(match.group('in'))
    outgoing = rxiface.findall(match.group('out'))

    result[key] = {'incoming': incoming, 'outgoing': outgoing}

print result
# {'192.168.1.1,232.0.6.8': {'outgoing': ['TenGigE0/0/0/10'], 'incoming': ['TenGigE0/0/0/1']}, '192.168.55.3,232.0.10.69': {'outgoing': ['TenGigE0/0/0/10', 'TenGigE0/3/0/0', 'TenGigE0/4/0/0'], 'incoming': ['TenGigE0/0/0/0', 'TenGigE0/1/0/0', 'TenGigE0/2/0/0']}}

关于python - 需要帮助解析 Cisco 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37958897/

相关文章:

python - 根据另一个数据帧的值将数据帧拆分为多个数据帧

python - 为什么文件夹中的所有图像没有显示在 Canvas 框架内的 tkinter 标签上?

javascript - 如何用模式分割字符串而不丢失任何文本?

c++ - 解析器帮助程序不工作

xml - 使用 XPath 选择下一个链接

python - 为第三方 HTTP 调用优化 Celery

python - 如何在 sympy 中创建向量函数?

javascript - 千位分隔符的正则表达式

c# - 正则表达式 用预定义的数字替换可变数量的 ******

python - 重新采样/上采样周期索引并使用数据的两个极端时间 "edges"