PHP提取自定义BBcode标签属性与值的解决方案求助
问题:BBcode自定义标签属性提取的PHP代码修正
需求说明
现有自定义BBcode标签:
[quote="abc" post_id='5' time='1728016909' user_id='117'] Around & Business 78 [/quote]
需要动态提取出如下格式的属性数组:
array( 'quote' => "abc", 'post_id' => '5', 'time' => '1728016909', 'user_id' => '117' );
现有问题代码
尝试了以下PHP代码,但未达到预期效果:
$string = "[quote='abc' post_id='5' time='1728016909' user_id='117']Around & Business 78[/quote]"; $dom = new DOMDocument; $dom->loadHTML($string); // [quote="abc" ...... $attr = array(); var_dump($dom->getElementsByTagName('quote')); foreach ($dom->getElementsByTagName('quote') as $tag) { foreach ($tag->attributes as $attribName => $attribNodeVal){ $attr[$attribName]=$tag->getAttribute($attribName); } } echo "<pre>"; print_r($attr);
问题原因
DOMDocument是用于解析标准HTML/XML的工具,自定义BBcode的[quote]并非合法HTML标签,loadHTML会将其解析为普通文本节点,无法通过getElementsByTagName获取对应元素,因此无法提取属性。
简易修正方案
方案1:使用正则表达式(推荐)
直接用正则匹配BBcode标签中的属性,是处理此类场景更高效的方式:
$string = "[quote='abc' post_id='5' time='1728016909' user_id='117']Around & Business 78[/quote]"; $attr = []; // 匹配quote标签的属性部分 if (preg_match('/\[quote(.*?)\]/', $string, $matches)) { // 匹配所有属性键值对,支持单/双引号包裹值 preg_match_all('/(\w+)\s*=\s*(["\'])(.*?)\2/', $matches[1], $attrs); // 整理为目标数组 foreach ($attrs[1] as $key => $name) { $attr[$name] = $attrs[3][$key]; } } echo "<pre>"; print_r($attr); echo "</pre>";
说明:
- 第一个正则捕获
[quote...]标签内的属性内容; - 第二个正则匹配每个属性的键名和对应值,自动兼容单引号、双引号包裹的格式;
- 最终输出的数组完全符合需求格式。
方案2:转换为自定义HTML标签后使用DOMDocument
如果坚持使用DOMDocument,可先将BBcode标签替换为自定义HTML标签,再进行解析:
$string = "[quote='abc' post_id='5' time='1728016909' user_id='117']Around & Business 78[/quote]"; // 将BBcode标签替换为自定义HTML标签 $htmlString = str_replace(['[quote', '[/quote]'], ['<quote', '</quote>'], $string); $dom = new DOMDocument; // 禁用libxml错误提示,避免自定义标签触发警告 libxml_use_internal_errors(true); $dom->loadHTML($htmlString); libxml_clear_errors(); $attr = []; $quoteTags = $dom->getElementsByTagName('quote'); if ($quoteTags->length > 0) { $tag = $quoteTags->item(0); foreach ($tag->attributes as $attribName => $attribNodeVal) { $attr[$attribName] = $tag->getAttribute($attribName); } } echo "<pre>"; print_r($attr); echo "</pre>";
内容的提问来源于stack exchange,提问作者Vipul Jethva
相关产品推荐
相关产品推荐

