我需要解析configraion文件,其中可能省略配置命令(因此我想将Optional
与default
一起使用)并且没有特定的顺序(所以我必须使用Each
) 。无论如何,让我们从有序的配置开始:
teststr = """
interface 4
frames tagged
exit
interface 5
pvid 17
exit
"""
portid = Word(nums)('portid')
pvid = Keyword('pvid').suppress() + Word(nums)('pvid')
frames = Keyword('frames').suppress() \
+ (Keyword('tagged') | Keyword('all'))
exit = Keyword('exit')
interface = Group(
Keyword('interface') + portid \
+ Optional(pvid) \
+ Optional(frames, default='all')('frames') \
+ exit
)
interface_list = Group(interface + ZeroOrMore(interface))('interfaces')
res = interface_list.parseString(teststr)
for iface in res.interfaces:
print '{}\n'.format(iface.dump())
这段代码给了我这个结果(没错,我相信---请注意frames
第一部分设为tagged
:
['interface', '4', 'tagged', 'exit']
- frames: ['tagged']
- portid: 4
['interface', '5', '17', 'all', 'exit']
- frames: ['all']
- portid: 5
- pvid: 17
但现在我想解析此配置,假设命令pvid
和frames
可以按任意顺序排列,所以我想使用{{1} } 这样:
Each
现在我错了(我相信)结果:
interface = pp.Group(
pp.Keyword('interface') + portid + (
pp.Optional(pvid)
& pp.Optional(frames, default='all')('frames')
) + exit)
我希望['interface', '4', 'tagged', 'all', 'exit']
- frames: ['all']
- portid: 4
['interface', '5', '17', 'all', 'all', 'exit']
- frames: ['all', 'all']
- portid: 5
- pvid: 17
返回与使用pyparsing
运算符时相同的结果。我错了吗?有什么问题?
答案 0 :(得分:0)
您使用的是什么版本的pyparsing?使用pyparsing 2.0.3,使用您的示例程序,我得到:
['interface', '4', 'tagged', 'exit']
- frames: ['tagged']
- portid: 4
['interface', '5', '17', 'all', 'exit']
- frames: ['all']
- portid: 5
- pvid: 17
答案 1 :(得分:0)
所以,我有2.0.3并将此补丁应用于它:
--- pyparsing-2.0.3.py 2015-07-16 17:30:16.705011488 +0300
+++ pyparsing-2.0.3-patched.py 2015-07-16 17:35:03.977015739 +0300
@@ -2811,6 +2811,9 @@
self.defaultValue = default
self.mayReturnEmpty = True
+ if self.defaultValue is not _optionalNotMatched:
+ self.mayReturnEmpty = False
+
def parseImpl( self, instring, loc, doActions=True ):
try:
loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False )
然后我更改了interface
的定义:
interface = pp.Group(
pp.Keyword('interface') + portid + (
pp.Optional(pvid)
& pp.Optional(frames('frames'), default='all')
) + exit)
这给了我最“直观”的结果,我会说:
['interface', '4', 'tagged', 'exit']
- frames: ['tagged']
- portid: 4
['interface', '5', '17', 'all', 'exit']
- frames: all
- portid: 5
- pvid: 17
该补丁不会破坏当前svn中的任何[更多]测试。无论如何,我不确定我知道自己在做什么,所以我仍在寻找答案。
@ paul-mcguire,对不起,升级到2.0.3并没有帮助我。
谢谢你。)