Home > Enterprise >  Regex to match anything inside a specific function
Regex to match anything inside a specific function

Time:01-06

I'm trying to extract all the queries from a PHP file. I use PHP reflection to retrieve the content of a method.

When I use reflection the string looks a bit like this:

        DB::statement('\n
            ALTER TABLE `activity` \n
            ADD `deleted_at` TIMESTAMP NULL\n
        ');\n
        DB::statement('\n
            ALTER TABLE `activity_recurrence` \n
            ADD `deleted_at` TIMESTAMP NULL\n
        ');\n

I'm trying to capture anything inside the statement() function. I've been trying a lot of different regex options but I'm unable to crack the case.

I'm now using this regex: ()\(([^)]*)\). It grabs anything between parenthesis but does not check if it has a statement suffix. I've been playing around with this answer, but I don't get it working.

Thanks in advance!

CodePudding user response:

If you want to anything inside the statement function, you might use a recursive pattern with 2 capture groups.

Then you can take the group 2 value.

\bDB::statement(\(((?>[^()]  |(?1))*)\))

Explanation

  • \bDB::statement
  • ( Capture group 1
    • \( Match (
    • ( Capture group 2
      • (?>[^()] |(?1))* Atomic group, match either 1 or more chars other than parenthesis, or recurse the first subpattern using (?1)
    • ) Close group 2
    • \) Match )
  • ) Close group 1

See a regex101 demo.

Note that can still be a brittle solution as you want to match sql statements.

CodePudding user response:

So arkascha set me in the right direction. Below is a vanilla PHP solution.

 /**
 * Get everything between 2 string parts
 *
 * @param  string  $body
 * @param  string  $startString
 * @param  string  $endString
 * @return array
 */
public function findBetween(string $body, string $startString, string $endString): array
{
    // Create an array where we can store everything
    $result = [];

    // Clean-up the string a bit
    $body = trim(preg_replace('/\s /', ' ', $body));

    while (true) {
        // Find the first occurrence of the start string
        $start = strpos($body, $startString);

        // If we can not find any recurrence of the start string we break-out of the loop
        if (! $start) {
            break;
        }

        // The start is actually the first occurrence   the length of the start
        $start = $start   strlen($startString);

        // Find the end of the string
        $end = strpos($body, $endString);

        // Add anything in between the start and end inside the array
        $result[] = substr($body, $start, ($end - $start));

        // Chop the first part of the body
        $body = substr($body, ($end   strlen($endString)));
    }

    return $result;
}

In my case I will be using it like this:

findBetween($body, 'statement(', ');');
  • Related