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(', ');');