使用 Python 的 textx 库,我无法从网络配置文件中准确捕获我想要的内容。我可以捕获接口及其属性信息,但我希望 textx 在将模型传递回我的代码之前完成大部分解析和过滤工作。我遇到的问题是 textx 解析所有数据而不进行过滤或捕获,我认为是所有目标数据,留下一些内容未解析或忽略。
对于语言的复杂性,我深表歉意。这是我当前要解析的文本,假设所呈现的数据块周围还有其他数据,解析器将根据后面显示的语法忽略这些数据:
网络配置文件
interface TenGigabitEthernet1/1/4
description Some interface
switchport trunk native vlan 232
switchport trunk allowed vlan 395,398
switchport mode trunk
switchport nonegotiate
no cdp enable
flowcontrol receive off
channel-group 1 mode active
lacp rate fast
!
interface Vlan1
no ip addr
语法.tx
Config:
(
Junk
| interface=INTERFACE
)*
;
Junk[noskipws]:
!(INTERFACE)/[^\n]*\n/
;
INTERFACE[noskipws]:
'interface' intf=/.+[0-9]+[^\n]*//\n/-
(mode+=MODE
attributes+=ATTRIBUTES)#
;
ATTRIBUTES[noskipws]:
!MODE/\s+[^\n]*//\n/-
;
MODE[noskipws]:
/\s+/'switchport mode trunk'/[^\n]*//\n/-
;
这里的目标是能够捕获
mode trunk
的接口及其所有定义 - 换句话说,Config.interface[...] 应该仅由 组成,而它应该忽略其他接口(Interface Vlan1
):
interface TenGigabitEthernet1/1/4
description Some interface
switchport trunk native vlan 232
switchport trunk allowed vlan 395,398
switchport mode trunk
switchport nonegotiate
no cdp enable
flowcontrol receive off
channel-group 1 mode active
lacp rate fast
但我发现代码捕获了:
interface TenGigabitEthernet1/1/4
description Some interface
switchport trunk native vlan 232
switchport trunk allowed vlan 395,398
switchport mode trunk
我推断这是因为语法的以下部分
ATTRIBUTES[noskipws]:
!MODE/\s+[^\n]*//\n/-
指示捕获之前没有的所有文本
switchport mode trunk
。所以我尝试使用以下表达式包含这两种模式:
ATTRIBUTES[noskipws]:
(!MODE/\s+[^\n]*//\n/-
|/\s+[^\n]*//\n/-!MODE)
虽然这导致了
len(Config.interface) == 0
我将继续阅读文档,但我会在这里发帖,以防有人可以看到我的错误所在。
Config:
(
Junk
| interface=INTERFACE
)*
;
Junk[noskipws]:
!(INTERFACE)/[^\n]*\n/
;
INTERFACE[noskipws]:
'interface' intf=/.+[0-9]+[^\n]*//\n/-
(mode+=MODE
attributes+=PREATTRIBUTES
attributes+=POSTATTRIBUTES
)#
;
PREATTRIBUTES:
!MODE
/\s+[^\n]*//\n/-
;
POSTATTRIBUTES:
/\s+[^\n]*//\n/-
!MODE
;
MODE:
/\s+/'switchport mode trunk'/[^\n]*//\n/-
;
通过此配置,只有具有“模式中继”的卡才会放入
interface
列表中,并且该接口对应的所有属性都会放入该接口的attributes
列表中。
虽然我认为
must
可以制作一个single ATTRIBUTES definition
。
我花了一些时间,但是以下语法可以解析 Cisco 配置文件,这些文件具有缩进依赖性,因此解析器需要考虑空格 - 我在解析时遇到了一些惊喜(主要是
'\n'
字符) -但通过这种方法,我能够遍历整个配置,并且只选择带有 switch mode trunk
配置条目的条目。
Config[noskipws]:
(
junk=JUNK
| interface=INTERFACE
)*
;
JUNK[noskipws]:
!INTERFACE/[^\n]*\n+/
;
INTERFACE[noskipws]:
'interface' /\s+/ name=/[^\n]*//\n+/-
(
( attributes=ATTRS)*
| mode+=MODE
| (attributes=ATTRS)*
)#
;
MODE[noskipws]:
INDENT TRUNK /[^\n]*//\n+/-
;
ATTRS[noskipws]:
INDENT !TRUNK /[^\n]*//\n+/-
;
INDENT[noskipws]:
/\s+/
;
TRUNK[noskipws]:
'switchport' /\s+/ 'mode' /\s+/ 'trunk'
;