无法获取pyparsing Dict()返回嵌套字典

kgr*_*kgr 12 python dictionary nested pyparsing

我正在尝试解析表单的字符串:

'foo(bar:baz;x:y)'
Run Code Online (Sandbox Code Playgroud)

我希望结果以嵌套字典的形式返回,即对于上面的字符串,结果应该如下所示:

{ 'foo' : { 'bar' : 'baz', 'x' : 'y' } }
Run Code Online (Sandbox Code Playgroud)

尽管有许多Dict()和Group()的组合,但我无法让它发挥作用.我的(其中一个版本)语法看起来像这样:

import pyparsing as pp
field_name = pp.Word( pp.alphanums )
field_value = pp.Word( pp.alphanums )
colon = pp.Suppress( pp.Literal( ':' ) )

expr = pp.Dict( 
    pp.Group( 
        field_name + \
        pp.nestedExpr( 
            content = pp.delimitedList( 
                 pp.Group( field_name + colon + field_value ), 
                 delim = ';' 
            ) 
        ) 
    ) 
)
Run Code Online (Sandbox Code Playgroud)

现在,结果如下:

In [62]: str = 'foo(bar:baz;x:y)'

In [63]: expr.parseString( str ).asList()
Out[63]: [['foo', [['bar', 'baz'], ['x', 'y']]]]

In [64]: expr.parseString( str ).asDict()
Out[64]: {'foo': ([(['bar', 'baz'], {}), (['x', 'y'], {})], {})}

In [65]: print( expr.parseString( str ).dump() )
Out[65]: [['foo', [['bar', 'baz'], ['x', 'y']]]]
         - foo: [['bar', 'baz'], ['x', 'y']]
Run Code Online (Sandbox Code Playgroud)

所以这个asList()版本看起来对我很好,应该会产生一个我想的字典.当然,鉴于(我理解它的方式,请纠正我)Dict()将使用列表的第一个元素作为键来解析标记列表,其余所有作为字典中该键的值.这可以在字典没有嵌套的情况下工作.例如在这种情况下:

expr = pp.Dict( 
    pp.delimitedList( 
        pp.Group( field_name + colon + field_value ), 
        delim = ';' 
    ) 
)

In [76]: expr.parseString( 'foo:bar;baz:x' ).asDict()
Out[76]: {'baz': 'x', 'foo': 'bar'}
Run Code Online (Sandbox Code Playgroud)

那么,问题是第一种情况(以及我对问题的理解)或者Dict()无法应对这种情况有什么问题?我可以asList()手动使用并将其转换为字典,但我宁愿进行pyparsing这样做:)

任何帮助或指示将非常感激.

谢谢.

Nik*_* B. 7

两个问题:

  • 您缺少pp.Dict周围pp.delimitedList,使asDict在内部结果正常工作
  • 你只是asDict在最外面的ParsingResult实例上调用,留下内在的ParsingResult"未被解释"

我尝试了以下方法:

from pyparsing import *
field_name = field_val = Word(alphanums)
colon = Suppress(Literal(':'))

expr = Dict(Group(
    field_name +
    nestedExpr(content =
        Dict(delimitedList( 
            Group(field_name + colon + field_value), 
            delim = ';' 
        ))
    )
))
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

>>> res = expr.parseString('foo(bar:baz;x:y)')
>>> type(res['foo'])
<class 'pyparsing.ParseResults'>
>>> { k:v.asDict() for k,v in res.asDict().items() }
{'foo': {'x': 'y', 'bar': 'baz'}}
Run Code Online (Sandbox Code Playgroud)