Regular expression for parse function arguments with functions

≯℡__Kan透↙ 提交于 2021-02-04 19:47:10

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!