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

PHP中将类WordPress短代码的字符串解析为数组的问题

问题

我正在使用Laravel开发一款页面构建器,尝试实现类WordPress风格的短代码功能。现有如下HTML字符串:

$string = '<div class="temp">
    [title type="text" tag="h2" value="This is my cool title" disabled some-attribute]
    [text type="text" tag="p" value="Lorem ipsum dolor sit amet"]
</div>';

目标是提取所有方括号内的短代码,转换为如下格式的数组:

[
  [
   "id" => "title",
   "type" => "text",
   "tag" => "h2",
   "value" => "This is my cool title",
   "disabled" => true,
   "some-attribute" => true
  ],
  [
   "id" => "text",
   "type" => "text",
   "tag" => "p",
   "value" => "Lorem ipsum dolor sit amet"
  ]
]

但现有代码通过explode(' ', $match)按空格拆分短代码时,会把引号内的空格也当作分隔符,导致结果混乱:

// Extract all brackets from the string
preg_match_all('/(?<=\[)[^\][]*(?=])/', $string, $matches);

$itemsArray = array();
// Explode each shortcode by spaces
foreach ($matches[0] as $match) {
    $shortcode = explode( ' ', $match );
    $itemArray = array();
    // split shortcode in attributes
    foreach ($shortcode as $key => $attr) {
        $temp = explode('=', $attr);
        // First attribute is the id
        if ($key === 0) {
            $itemArray['id'] = $temp[0];
        } else {
            if ( count($temp) > 1 ) {
                $itemArray[ $temp[0] ] = trim($temp[1],'"');
            } else {
                $itemArray[ $temp[0] ] = true;
            }
        }
    }
    $itemsArray[] = $itemArray;
}

错误输出结果:

[
  [
    "id" => "title"
    "type" => "text"
    "tag" => "h2"
    "value" => "This"
    "is" => true
    "my" => true
    "cool" => true
    "title"" => true
    "disabled" => true
    "some-attribute" => true
  ],
  [
    "id" => "text"
    "type" => "text"
    "tag" => "p"
    "value" => "Lorem"
    "ipsum" => true
    "dolor" => true
    "sit" => true
    "amet"" => true
  ]
]

需要解决:如何拆分短代码时忽略引号内的空格?

解决方案

核心思路是放弃用explode按空格拆分,改用正则表达式精准匹配每个属性项,包括带空格的引号内值。修正后的代码如下:

// 提取所有方括号内的短代码内容
preg_match_all('/(?<=\[)[^\][]*(?=])/', $string, $matches);

$itemsArray = [];

foreach ($matches[0] as $match) {
    $itemArray = [];
    
    // 提取短代码ID(开头的标识)
    preg_match('/^\w+/', $match, $idMatch);
    $itemArray['id'] = $idMatch[0];
    
    // 匹配所有属性:支持 key="value(含空格)" 和 standalone-attr 两种格式
    preg_match_all('/(\w+-?\w+)(?:="([^"]*)")?/', $match, $attrMatches, PREG_SET_ORDER);
    
    foreach ($attrMatches as $attr) {
        // 跳过已经提取的ID项
        if ($attr[1] === $itemArray['id']) {
            continue;
        }
        
        // 有值则赋值,无值则设为true
        if (isset($attr[2])) {
            $itemArray[$attr[1]] = $attr[2];
        } else {
            $itemArray[$attr[1]] = true;
        }
    }
    
    $itemsArray[] = $itemArray;
}

// 输出验证结果
print_r($itemsArray);

关键逻辑说明

  1. 提取短代码ID:用/^\w+/匹配短代码开头的标识(比如title、text)。
  2. 匹配属性的正则:/(\w+-?\w+)(?:="([^"]*)")?/
    • (\w+-?\w+):匹配属性名,支持带连字符的格式(如some-attribute)。
    • (?:="([^"]*)")?:可选的属性值部分,[^"]*会匹配双引号内的所有内容(包括空格),不会被空格打断。
  3. 处理属性:遍历匹配到的属性,跳过ID项,有值则直接赋值,无值的独立属性设为true。

运行这段代码后,就能得到符合预期的数组结构,正确保留引号内的空格内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:12:07