将字符串短代码转换为没有wordpress函数的数组

时间:2017-06-11 11:08:36

标签: php regex wordpress parsing shortcode

我有一个包含多个短代码的字符串,如下所示:

// string contain multi shortcode
$string = '[code_1]
[code_2 attr_2="test2"]Here2[/code_2]
[code_3 attr_3="test3"]Here3[/code_3]
[code_4 attr_4="test4"]
    [code_4_1 attr_41="test41"]Here41[/code_4_1]
    [code_4_2 attr_42="test42"]Here42[/code_4_2]
[/code_4]';

我有一个包含短代码名称的列表键数组:

// list key
$list_key = array(
        'code_1',
        'code_2',
        'code_3',
        'code_4',
        'code_4_1',
        'code_4_2',
    );

如何生成以下数组?

array(
    array(
        "name" => "code_1",
    ),
    array(
        "name" => "code_2",
        "attr" => array(
            "attr_2" => "test2"
        ),
        "content" => "Here2",
    ),
    array(
        "name" => "code_3",
        "attr" => array(
            "attr_3" => "test3"
        ),
        "content" => "Here3",
    ),
    array(
        "name" => "code_4",
        "attr" => array(
            "attr_4" => "test4"
        ),
        "content" => array(
            array(
                "name" => "code_4_1",
                "attr" => array(
                    "attr_41" => "test41"
                ),
                "content" => "Here41",
            ),
            array(
                "name" => "code_4_2",
                "attr" => array(
                    "attr_42" => "test42"
                ),
                "content" => "Here42",
            )
        ),
    )
);

我想在Wordpress之外做这件事。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

首先,有很多方法可以做到这一点 其次,你应该用你的问题发布你的编码尝试(但我会假设你不知道如何处理它)
第三,我编写了一个方法,可以输入你的样本(字面意思)并产生你想要的输出(字面意思)。

当捕获的值中存在符号或换行符时,可能会出现问题,从正则表达式模式开始。在每个问题编辑后,我不想被编入多个答案编辑。我希望您能够修改我的答案以满足您的特定需求。将来,当您寻求基于正则表达式的解决方案时,当您提供至少2或3个不同的实际输入进行测试时,您将获得更高质量的答案。

Pattern Demo
代码(PHP Demo):

$in='[code_1]
[code_2 attr_2="test2"]Here2[/code_2]
[code_3 attr_3="test3"]Here3[/code_3]
[code_4 attr_4="test4"]
    [code_4_1 attr_41="test41"]Here41[/code_4_1]
    [code_4_2 attr_42="test42"]Here42[/code_4_2]
[/code_4]';

preg_match_all('/\[(code_\d+)(_\d+)?(?: (attr_\d+)="([^"]*)")?\](.+(?=\[\/\1\2?\]))?/',$in,$out,PREG_SET_ORDER);
$i=0;
foreach($out as $sc){
    if(!empty($sc[2]) && ($parent_i=array_search($sc[1],array_column($out,1)))!==false){
        // store child data in parent's content array
        $shortcodes[$parent_i]['content'][]=['name'=>$sc[1].$sc[2],'attr'=>[$sc[3]],'content'=>$sc[4]];
    }else{
        $tmp=['name'=>$sc[1]];                // declare a fresh tmp array
        if(isset($sc[3]) && isset($sc[4])){
            $tmp['attr']=[$sc[3]=>$sc[4]];    // store attr if available
        }
        if(isset($sc[5])){
            $tmp['content']=$sc[5];           // if text, store string
        }elseif(sizeof(array_keys(array_column($out,0),$sc[1]))){  // look for content or children
            $tmp['content']=[];               // if parent, declare empty array
        }
        $shortcodes[$i]=$tmp;                 // store built $tmp array
        ++$i;
    }
}
var_export($shortcodes);
// output as desired by OP