Suppose I have a string such as the following:
"func(arg1, arg2, arg3, arg4, ..., argn)"
EDIT: This function is not in some particular language. It just has this format. If it makes it easier, don't think of it as a function call, just a string.
I want to write a regular expression to match the function and each of the arguments. I am writing this in Python. The desired output of this is:
{"function" : "func", "arg" : ["arg1", "arg2", ... , "argn"]}
EDIT: While the arguments could be function calls, I can easily recursively try to match them with the same regular expression once I create one that works. By this I mean I can recurse on the function with each of the arguments. But this is not really relevant. I am not trying to create an interpreter, just something to recognize the arguments.
Here is my attempt at this:
import re
s = "func(arg1, arg2, arg3, arg4, argn)"
m = re.match(r"(?P<function>\w+)\s?\((?P<args>(?P<arg>\w+(,\s?)?)+)\)", s)
print m.groupdict()
And here is the output:
{'function': 'func', 'args': 'arg1, arg2, arg3, arg4, argn', 'arg': 'argn'}
The function matches just fine, and so does the argument set. However, I can't seem to match the individual arguments. Is this a problem with my regex, or a limitation of Python regular expression matching?
EDIT2: I am aware that I can now split the arguments using the following code:
d["arg"] = d["args"].split(", ")
But I was wondering if I could do the whole job with regular expressions. In particular, I am wondering why "arg" is matched to only the last argument.
EDIT3: I guess I am (1) hoping to figure out why Python only matches the last argument every time, and (2) whether I can do Scheme-style pattern-matching in Python. Or if there is something just as intuitive in Python as Scheme-style pattern matching. I looked at the ast module, and its syntax is prohibitively complex.
[] denotes a character class. () denotes a capturing group. [a-z0-9] -- One character that is in the range of a-z OR 0-9. (a-z0-9) -- Explicit capture of a-z0-9 .
Throw in an * (asterisk), and it will match everything. Read more. \s (whitespace metacharacter) will match any whitespace character (space; tab; line break; ...), and \S (opposite of \s ) will match anything that is not a whitespace character.
A regular expression (or RE) specifies a set of strings that matches it; the functions in this module let you check if a particular string matches a given regular expression (or if a given regular expression matches a particular string, which comes down to the same thing).
By default, regular expressions will match any part of a string. It's often useful to anchor the regular expression so that it matches from the start or end of the string: ^ matches the start of string. $ matches the end of the string.
Regular expressions cannot parse complex programming languages.
If you're just trying to parse Python, I suggest taking a look at the ast module, which will parse it for you.
Looks like you're 90% there, why not just swap the arg
and args
groupings and do:
import re
fn_match = re.match(r"(?P<function>\w+)\s?\((?P<arg>(?P<args>\w+(,\s?)?)+)\)", s)
fn_dict = fn_match.groupdict()
del fn_dict['args']
fn_dict['arg'] = [arg.strip() for arg in fn_dict['arg'].split(',')]
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