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
相关产品推荐
相关产品推荐

