I'm trying to parse strings of the form:
'foo(bar:baz;x:y)'
I'd like the results to be returned in form of a nested dictionary, i.e. for the above string, the results should look like this:
{ 'foo' : { 'bar' : 'baz', 'x' : 'y' } }
Despite numerous combinations of Dict() and Group() I can't get it to work. My (one of the versions of) grammar looks like this:
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 = ';'
)
)
)
)
and now, the results are as follows:
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']]
So the asList()
version looks quite good to me and should yield a dictionary I'm after I think. Of course given that (the way I understand it, please correct me) Dict() will parse lists of tokens by using the first element of the list as a key and all the rest as values of that key in a dictionary. This works insofar the dictionary is not nested. For example in such case:
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'}
So, the question is what is wrong with the first case (and my understanding of the problem) or perhaps Dict() can't cope with such case? I could use asList()
and convert that manually into a dictionary, but I'd rather have pyparsing do it :)
Any help or directions would be greately appreciated.
Thank you.
Two problems:
pp.Dict
around pp.delimitedList
to make asDict
on the inner result work correctlyasDict
on the outermost ParsingResult
instance, leaving the inner ParsingResult
"uninterpreted"I tried the following:
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 = ';'
))
)
))
Then used it like this:
>>> 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'}}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With