问题
I want to get the function arguments of string.
sample( 5*5 ) euros
This works correctly with:
([^\s\)]+)\(([^\)]+)\)
Demo here.
The problem is when I put another function inside the argument:
sample( decimal( 5*5 ) ) euros
With only a function this works with:
([^\s\)]+)\((.+)\)
Demo here.
But with two functions or more I can't get the function arguments:
sample( decimal( 5*5 ) ) toString(euros)
How can I get the function arguments with a regular expression?.
回答1:
If you are writing a parser you can do without a regex. From the educational point of view, in PHP PCRE regex, you can use recursion and subroutine calls.
Have a look at
(?<name>[^\s()]+)(\((?<body>(?>[^()]++|(?2))*)\))
See the regex demo
Group "name" will contain the function name and "body" group will hold what is inside the matching parentheses.
Note you need to add both ( and ) to the negated character class (?<funcion>[^\s()]+) because in case you have sample(decimal(3*3)) this group will grab the substring up to the ) (sample(decimal). Thus, you need to exclude both ( and ).
The (\((?<body>(?>[^()]++|(?2))*)\)) part is a capture group (with ID=2) that can be recursed (i.e. "repeated", "expanded" many times) with a subroutine call (?2).
It matches
\(- an open round bracket(?<body>(?>[^()]++|(?2))*)- Group "body" that matches zero or more sequences of:[^()]++- 1+ characters other than(and)or(?2)- the whole\((?<body>(?>[^()]++|(?2))*)\)subpattern
\)- a closing parenthesis
The (?2) subroutine call necessity (as compared to recursion with (?R)) is dictated by the fact that we need to repeat/recurse a part of the pattern.
Since Group 2 is a "technical" capture group, it might be a good idea to use named capture groups for those parts we want to really use.
回答2:
Use a look ahead that specifies the next bracket char (if any) is an open one, and use a relucant quantifier.
This should work:
([^\s\)]+)\((.+?)\)(?=[^()]*(\(|$))
来源:https://stackoverflow.com/questions/38430089/regular-expression-for-parse-function-arguments-with-functions