好吧,如果您能够使用较新regex module
的 in Python
,您可以定义子模式并使用以下方法:
- 在开始时为 IP 地址定义子模式
- ...以及传入和传出接口
- 分别解析接口
- 在 regex101.com 上查看演示。
定义子模式
Incoming
为 the和Outgoing Interface
字符串、theIP adress
和 end定义子模式。
(?(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)
解析传入/传出部分
由于您只需要接口类型/名称,您可以简单地提出:
TenGig\S+ # TenGig, followed by anything NOT a whitespace
提示
您实际上并不需要定义子模式,但是您需要经常重复自己(因为 neg.lookaheads)。因此,如果您需要坚持使用原始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']}}