Я пытаюсь разобрать строки вида:
'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:)
Любая помощь или указания будут с благодарностью приняты.
Спасибо.