2

I'm trying to parse some functions arguments with PyParsing but am having trouble getting the right syntax. Namely, given:

str = "(key=val())"

I would like the parser to return ['key', 'val()'].

I've been trying to get this to work with the following code; the .suppress() calls are intentionally omitted for clarity.

ob = Literal("(")
cb = Literal(")")
key = Word(alphas)
value = Word(alpha + "()") 
parser = ob + key + "=" + value + cb
print parser.parseString(str)

but of course it's matching the final closing bracket as well and so I get a ParseException.

Is there an elegant solution to this? For example, I looked at nestedExpr but in this case it's not strictly a nesting since I want the val() to be treated as a literal. Similarly this question alludes to the problem but doesn't give a solution.

Community
  • 1
  • 1
jkeirstead
  • 2,881
  • 3
  • 23
  • 26

1 Answers1

0

Your definition of

value = Word(alpha + "()")

is overly liberal. Not only will it match trailing ()'s, but also any embedded ones, and regardless of matching opening and closing, values like:

SLDFJJ(sldkjf)
sdlkfj(sldkfj(lkskdjf)))(

and even just:

(((((())(()()()()

I suggest you define the syntax for an identifier, usually something like:

identifier = Word(alphas+'_', alphanums+'_')

and then compose value with:

value = Combine(identifier + '()')

Now the value expression won't erroneously accept any embedded ()s, and will only parse the trailing () and nothing further.

PaulMcG
  • 62,419
  • 16
  • 94
  • 130