Sunday, 11 August 2013

Compact way to parse a list and dict

Compact way to parse a list and dict

I would like a compact way to parse one-line strings that start with
mandatory list-elements (unspecified number) and ends with dictionary-like
definitions using =.
The element-separator should be , and spaces should become part of the
element -- which rules out shlex, I think.
Spaces should/may be stripped at the start and end (quotes, too)
If an element would contain a , the user is required to quote with "
either "key=value,with,comma"</li> <li>orkey="value,with,comma" --
whatever is easier to implement
It's ok to have undefined behavior with wrong quoting or with elements
containing a quote-char.
Behaviour with double keys is also undefined.
Slight variations of this are ok if it simplifies the implementation a lot.
Lets call the function opts and have it return a list and a dict,
Here are some input examples and desired results:
opts('dog,cat') # -> ["dog", "cat"], {}
opts('big fish,cat') # -> ["big fish", "cat"], {}
opts('"a dog, a cat";a fish') # -> ["a dog, a cat", "a fish"], {}
opts('key=value') # -> [] {'key':'value'}
opts('key=the value,x=y') # -> [] {'key':'the value', 'x':'y'}
opts('dog, big fish, eats="any, but peas", flies = no! '
# -> ['dog','big fish'], {'eats':'any, but peas', 'flies':'no!' }
I disregarded shlex, argparse, optparse and configparser, I can't see how
I should do it with those. I am not sure if Regular Expressions crack this
nut, though.
My manual solution in macro is not very flexible and I would like to have
its parameter handling be replaced by the more general opts(s) function
described above:
def macro(s):
kw = { 'see':u"\\see", 'type':u"Chapter", 'title': u'??' }
params = s.split(",")
kw['label'] = params[0]
if len(params) > 1: # very inflexible
kw['title'] = params[1]
for param in params[2:]: # wrong if p[1] is already
key=value
key, value = paream.split("=",1) # doesn't handle anything, too
simple
kw[key] = value
# ...rest of code...
The goal is to have the reusable function opts to be used here:
def macro_see(s):
ls, kw = opts(s)
# ...rest of code...

No comments:

Post a Comment