Search code examples
phpregexvqmod

How to match paired closing bracket with regex


My current regex matches a function name and the variable name passed to the function see here

Regex - (file_exists|is_file)\(([^)]+)
string if (is_file($file)){
Matches is_file and $file

I would also like the regex to work with a string rather than just a variable name, This includes strings with multiple opening and closing brackets.

Here's an extreme example.

Regex - (file_exists|is_file)\(????????)
string if (is_file(str_replace(array('olddir'), array('newdir'), strtolower($file))){
Matches is_file and str_replace(array('olddir'), array('newdir'), strtolower($file)

Is there a way to match the next closing bracket, unless one has been opened?

I would like to get it working at regex101


Solution

  • You can use a regex with a subroutine call in PHP:

    '~(file_exists|is_file)(\(((?>[^()]++|(?2))*)\))~'
    

    See the regex demo

    The pattern matches:

    • (file_exists|is_file) - one of the two alternatives
    • (\(((?>[^()]++|(?2))*)\)) - Group 1 matching paired nested (...) substrings, and ((?>[^()]++|(?2))*) is Group 3 capturing the contents inside the outer paired (...).

    Thus, the results are:

    • Group 1: is_file
    • Group 2: (str_replace(array(), array(), strtolower($file)))
    • Group 3: str_replace(array(), array(), strtolower($file))

    Use Group 1 and 3.