使用Python textx解析网络配置:trunk模式接口捕获问题
问题:用textX解析网络配置时捕获带trunk模式的接口及全部属性
我在用Python的textX库解析网络配置文件时,需要实现以下需求:
- 解析阶段完成过滤,仅保留包含
switchport mode trunk的接口及其所有属性 - 忽略无该模式的接口(比如示例中的Vlan1)
但当前的grammar只能捕获mode之前的属性,修改ATTRIBUTES规则试图覆盖mode前后内容后,出现len(Config.interface) == 0的问题。目前通过拆分属性为PRE/POST的方案能实现功能,但不够优雅,希望找到用单一ATTRIBUTES定义的实现方式。
待解析的网络配置文件
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
初始grammar.tx(仅能捕获mode前的属性)
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/- ;
失败的修改尝试(导致无接口被捕获)
修改ATTRIBUTES规则试图匹配mode前后的属性:
ATTRIBUTES[noskipws]: (!MODE/\s+[^\n]*//\n/- |/\s+[^\n]*//\n/-!MODE)
非理想解决方案(拆分属性为PRE/POST)
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/- ;
单一ATTRIBUTES规则的解决方案
通过语义谓词过滤接口,并调整INTERFACE规则的匹配顺序,实现用单一ATTRIBUTES规则捕获所有属性:
Config: ( Junk | interface=INTERFACE[has_trunk_mode] // 仅保留包含trunk模式的接口 )* ; Junk[noskipws]: !(INTERFACE)/[^\n]*\n/ ; INTERFACE[noskipws]: 'interface' intf=/.+[0-9]+[^\n]*//\n/- ( (attributes+=ATTRIBUTES | mode=MODE)* // 无序匹配所有属性行和mode行 ) ; // 语义谓词:验证接口是否包含trunk模式 predicate has_trunk_mode(iface): return hasattr(iface, 'mode') ATTRIBUTES[noskipws]: !MODE/\s+[^\n]*//\n/- // 匹配所有非mode的属性行 ; MODE[noskipws]: /\s+/'switchport mode trunk'/[^\n]*//\n/- ;
方案说明
- 无序匹配结构:INTERFACE规则中用
(attributes+=ATTRIBUTES | mode=MODE)*,允许属性行和mode行以任意顺序出现,这样不管mode在接口配置的哪个位置,所有非mode属性都会被捕获到attributes列表,mode单独存为字段。 - 语义谓词过滤:给INTERFACE加上
has_trunk_mode谓词,解析时自动过滤掉没有mode字段的接口,确保最终模型只保留符合要求的接口。 - 单一ATTRIBUTES规则:保持ATTRIBUTES规则简洁,仅匹配所有不是mode的属性行,无需拆分PRE/POST。
解析示例配置后,Config.interface中只会包含TenGigabitEthernet1/1/4,其attributes包含mode前后的所有属性行,且mode字段存在。
内容的提问来源于stack exchange,提问作者user190270
相关产品推荐
相关产品推荐

