You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP正则提取赋值给变量的Lambda函数体返回NULL如何解决

PHP匿名函数体提取正则匹配失败修复

问题背景

现有可正常工作的具名函数体提取函数extractBody(),实现代码如下:

$data = '
    <?php 
    function my_function($param){
        if($param === true){
            // This is true
        }else if($param === false){
            // This is false
        }else{
            // This is not
        }
    }
    ?>
';

function extractBody($functionName, $data) {
    $c = preg_match_all("/function\s+".$functionName."\s*\((?<param>[^\)]*)\)\s*(?<body>\{(?:[^{}]+|(?&body))*\})/", $data, $matches);
    return $c > 0 ? $matches['body'] : null;
}

$body = extractBody("my_function", $data);
var_dump($body);

运行后$body可正确获取函数主体内容:

if($param === true){
            // This is true
        }else if($param === false){
            // This is false
        }else{
            // This is not
        }

现在需要开发提取赋值给变量的Lambda匿名函数体的函数extractBody2(),测试代码如下:

$data2 = '
    <?php 
    $my_function = function($param){
        if($param === true){
            // This is true
        }else if($param === false){
            // This is false
        }else{
            // This is not
        }
    }
    ?>
';

function extractBody2($functionName, $data) {
    $c = preg_match_all("/".$functionName."\s+=\s+function\s+\s*\((?<param>[^\)]*)\)\s*(?<body>\{(?:[^{}]+|(?&body))*\})/", $data, $matches);
    return $c > 0 ? $matches['body'] : null;
}

$body2 = extractBody2("my_function", $data2);
var_dump($body2);

运行后返回结果为NULL,无法正确提取函数体。

故障原因

正则逻辑存在三个问题:

  • 未匹配PHP变量前缀的$符号:传入的函数名参数是my_function,但代码中实际变量写为$my_function,正则开头直接拼接函数名,完全跳过了前缀$的匹配,无法命中目标片段
  • 未转义正则元字符:$是正则中的特殊元字符,默认代表行/字符串结尾位置,就算手动在正则中补上$,不做转义也会导致正则匹配逻辑完全失效,无法匹配字面意义的$符号
  • 匹配规则兼容性差:原正则用\s+要求等号、function关键字前后必须存在至少1个空白字符,遇到$f=function(){}这类无空格的写法会匹配失败,且function\s+\s*属于冗余的重复空白匹配,没有实际意义

修正方案

调整正则逻辑:

  1. 正则开头增加转义后的\$匹配PHP变量前缀
  2. 用preg_quote()处理传入的函数名,避免函数名中存在其他正则特殊字符导致匹配异常
  3. 将冗余/严格的\s+改为\s*,兼容0个或多个空白的写法,提升适配性

修正后的函数代码:

function extractBody2($functionName, $data) {
    // 拼接正则:转义$符号,转义函数名特殊字符,调整空白匹配规则
    $pattern = "/\\\$" . preg_quote($functionName, '/') . "\s*=\s*function\s*\((?<param>[^\)]*)\)\s*(?<body>\{(?:[^{}]+|(?&body))*\})/";
    $c = preg_match_all($pattern, $data, $matches);
    return $c > 0 ? $matches['body'] : null;
}

运行测试代码后,$body2可正确返回匿名函数的主体内容,和具名函数提取结果一致。

内容的提问来源于stack exchange,提问作者smolo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 22:36:20