Не удается получить pyparsing Dict () для возврата вложенного словаря - PullRequest
11 голосов
/ 03 апреля 2012

Я пытаюсь разобрать строки вида:

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

Я бы хотел, чтобы результаты возвращались в виде вложенного словаря, т.е. для приведенной выше строки результаты должны выглядеть следующим образомthis:

{ '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:)

Любая помощь или указания будут с благодарностью приняты.

Спасибо.

1 Ответ

7 голосов
/ 03 апреля 2012

Две проблемы:

  • Вам не хватает 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'}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...