PHP嵌套color类BBCode解析代码选型及修复方案咨询
BBCode嵌套color标签解析方案
选型结论
版本02的实现思路更适合作为迭代基础。
- 版本01的整组非贪婪匹配思路本质是将BBCode标签视为线性无嵌套结构,正则匹配时会自动将第一个开标签与扫描到的第一个闭标签配对,从底层逻辑上就不支持嵌套场景,没有改造价值。
- 版本02拆分匹配开标签、闭标签的方向符合嵌套结构解析的基本逻辑,当前存在的问题仅为正则规则不严谨、缺少标签配对校验逻辑,修复成本极低。
版本02现存问题
- 开、闭标签的正则规则未完整匹配方括号,导致解析结果中残留多余的
[字符 - 单次正则替换无上下文感知能力,无法校验标签配对关系,遇到未闭合标签、多余闭标签时会输出非法HTML结构,也无法正确对应嵌套层级的标签关系
可支持任意层级嵌套的完整实现
正则本身无法完美处理任意深度的嵌套结构,这类上下文相关的解析场景使用栈结构做标签配对是最稳妥的方案,同时可顺带实现XSS防护、异常标签兼容能力:
function FFF999_BBcode($content) { // 先转义HTML特殊字符,防范XSS风险 $content = htmlspecialchars($content, ENT_QUOTES, 'UTF-8'); $parsedResult = ''; // 维护颜色栈,存储嵌套层级的颜色值 $colorStack = []; // 拆分内容,分离普通文本、color开标签、color闭标签 $segments = preg_split( '/(\[color=[^\]]+\]|\[\/color\])/i', $content, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); foreach ($segments as $segment) { // 匹配合法color开标签 if (preg_match('/^\[color=([^\]]+)\]$/i', $segment, $match)) { $colorValue = trim($match[1]); // 校验颜色值格式合法性,可按需扩展规则 if (preg_match('/^[a-z0-9#(),\s%]+$/i', $colorValue)) { array_push($colorStack, $colorValue); $parsedResult .= '<span style="color: ' . $colorValue . '">'; continue; } } // 匹配color闭标签 if (strcasecmp($segment, '[/color]') === 0) { if (!empty($colorStack)) { array_pop($colorStack); $parsedResult .= '</span>'; continue; } } // 普通文本、非法标签、多余闭标签直接追加 $parsedResult .= $segment; } // 补全所有未闭合的开标签 while (!empty($colorStack)) { array_pop($colorStack); $parsedResult .= '</span>'; } return $parsedResult; }
测试验证
传入测试用例[color=red][color=blue]test test test[/color][/color],解析结果为:
<span style="color: red"><span style="color: blue">test test test</span></span>
完全符合预期,同时支持3层及以上的color标签嵌套,可自动处理标签不闭合、多余闭标签、非法颜色值等异常输入。
内容的提问来源于stack exchange,提问作者xrescom
相关产品推荐
相关产品推荐

