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

PHP字符串对比提取变量异常,仅前两个变量有值求解决方案

问题分析与解决方案

我看了你的代码,问题出在你用explode分割字符串的思路上:这种方法完全依赖模板分割段和编辑后字符串的精确字符匹配,一旦中间某段的分割符没找到(比如你处理完前两个变量后,剩下的编辑字符串和下一个模板分割段完全不匹配),后续所有变量都会提取失败,返回空值。

更可靠的方法是把模板转换成正则表达式,用捕获组一次性匹配所有占位符对应的内容。这样只要模板和编辑后的字符串结构一致,就能准确提取所有变量值。

修复后的代码

$template = '<div[string:class_cover_ratio]><div[string:class_2]><div class="cbp-caption-defaultWrap"><img src="data:image/gif;base64,R0lGODlhAQABAPAAAP///////yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="" data-cbp-src="[image:thumbnail_name]" width="[string:large_width]" height="[string:large_height]"></div><div class="cbp-caption-activeWrap"><div class="cbp-l-caption-alignCenter"><div class="cbp-l-caption-body"><a href="[image:large_name]" class="cbp-lightbox cbp-l-caption-buttonLeft" data-title="[string:title]">[string:view_larger_text]</a></div></div></div></div><div class="cbp-l-grid-projects-title">[string:dish_name]</div><div class="cbp-l-grid-projects-desc">[string:dish_description]</div></div>';
$edited = '<div class="cbp-item logos cbp-ratio-even" data-cbp-coverratio="4:3"><div class="cbp-caption" style=""><div class="cbp-caption-defaultWrap"><img src="data:image/gif;base64,R0lGODlhAQABAPAAAP///////yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="" data-cbp-src="http://cubewp.axcelmedia.com/wp-content/uploads/2019/01/Ankimo-thum.jpg" width="400" height="300"></div><div class="cbp-caption-activeWrap"><div class="cbp-l-caption-alignCenter"><div class="cbp-l-caption-body"><a href="http://cubewp.axcelmedia.com/wp-content/uploads/2019/01/Ankimo.jpg" class="cbp-lightbox cbp-l-caption-buttonLeft" data-title="Monkfish Liver, lightly garnished">View Larger</a></div></div></div></div><div class="cbp-l-grid-projects-title">Ankimo</div><div class="cbp-l-grid-projects-desc">Monkfish Liver, lightly garnished</div></div>';

function test($edited, $template) {
    $gottenValues = [];
    
    // 1. 提取模板中所有的占位符(比如 [string:class_cover_ratio])
    preg_match_all('/\[([^\]]+)\]/', $template, $matches);
    $placeholders = $matches[1];
    
    // 2. 将模板转换为正则表达式:转义特殊字符,替换占位符为捕获组
    $pattern = preg_quote($template, '/');
    $pattern = preg_replace('/\\\[([^\]]+)\\\]/', '(.*?)', $pattern);
    
    // 3. 添加锚点确保完全匹配,/s修饰符让.匹配换行符(兼容含换行的模板)
    $pattern = '/^' . $pattern . '$/s';
    
    // 4. 匹配编辑后的字符串,提取所有捕获组的值
    if (preg_match($pattern, $edited, $values)) {
        array_shift($values); // 移除整个匹配的字符串,只保留捕获组
        $gottenValues = array_combine($placeholders, $values);
    }
    
    echo '<pre>';
    print_r($gottenValues);
    die;
}

test($edited, $template);

输出结果

Array
(
    [string:class_cover_ratio] => class="cbp-item logos cbp-ratio-even" data-cbp-coverratio="4:3"
    [string:class_2] => class="cbp-caption" style=""
    [image:thumbnail_name] => http://cubewp.axcelmedia.com/wp-content/uploads/2019/01/Ankimo-thum.jpg
    [string:large_width] => 400
    [string:large_height] => 300
    [image:large_name] => http://cubewp.axcelmedia.com/wp-content/uploads/2019/01/Ankimo.jpg
    [string:title] => Monkfish Liver, lightly garnished
    [string:view_larger_text] => View Larger
    [string:dish_name] => Ankimo
    [string:dish_description] => Monkfish Liver, lightly garnished
)

为什么这个方法更可靠?

  • 正则捕获组是基于整体结构匹配,而不是逐段分割,避免了某一段分割失败导致后续全部失效的问题。
  • preg_quote自动转义模板中的正则特殊字符(比如.、"、/等),确保模板的静态部分能被正确匹配。
  • (.*?)是非贪婪匹配,只会捕获到下一个模板静态部分之前的内容,不会出现过度匹配的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:14:50