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

发布于 2021-01-29 16:08:18

我试图解析形式的字符串:

'foo(bar:baz;x:y)'

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

{ 'foo' : { 'bar' : 'baz', 'x' : 'y' } }

尽管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 = ';' 
            ) 
        ) 
    ) 
)

现在,结果如下:

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']]

因此,该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'}

因此,问题是第一种情况(以及我对问题的理解)有什么问题,或者Dict()无法解决这种情况?我可以asList()手动使用并将其转换成字典,但我希望pyparsing做到这一点:)

任何帮助或指示将不胜感激。

谢谢。

关注者
0
被浏览
45
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    两个问题:

    • 您缺少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 = ';' 
            ))
        )
    ))
    

    然后像这样使用它:

    >>> 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'}}
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看