regex 正则表达式匹配特定函数中的任何内容

jum4pzuy  于 2023-01-06  发布在  其他
关注(0)|答案(2)|浏览(171)

我正在尝试从一个PHP文件中提取所有的查询。我使用PHP反射来检索一个方法的内容。
当我使用反射时,字符串看起来有点像这样:

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

我试图捕获statement()函数中的任何内容。我已经尝试了很多不同的正则表达式选项,但我无法破解这个问题。
我现在使用这个正则表达式:()\(([^)]*)\)。它抓取括号之间的任何内容,但不检查它是否有statement后缀。我一直在尝试使用这个answer,但我无法让它工作。
先谢了!

cnwbcb6i

cnwbcb6i1#

如果您想在语句函数内部执行任何操作,可以使用带有2个捕获组的递归模式。
然后可以取第2组的值。

\bDB::statement(\(((?>[^()]++|(?1))*)\))
    • 说明**
  • 第一个月
  • (捕获组1
  • \(匹配(
  • (捕获组2
  • (?>[^()]++|(?1))*原子组,匹配除括号外的1个或多个字符,或使用(?1)递归第一个子模式
  • )关闭组2
  • \)匹配)
  • )关闭组1

参见regex101 demo

    • 注意**当您想要匹配sql语句时,这仍然是一个脆弱的解决方案。
lmyy7pcs

lmyy7pcs2#

所以arkascha为我指明了正确的方向。下面是一个普通的PHP解决方案。

/**
 * 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;
}

在我的例子中,我将这样使用它:

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

相关问题