0

I have a string containing multiple shortcodes like this:

// 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]';

And I have a list key array containing shortcode names:

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

How can I generate the following array?

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",
            )
        ),
    )
);

I want to do this outside of Wordpress. How can I do that?

0

1 Answer 1

1

First, there will be many ways to do this.
Second, you should have posted your coding attempt with your question (but I'll assume you had no clue how to tackle it)
Third, I have written a method that will take your sample input (literally) and produce your desired output (literally).

Problems may arise, starting with the regex pattern, when symbols or newline characters exist in the captured values. I would not like to get roped into multiple answer edits after each question edit. I hope you will be able to modify my answer to suit your specific needs. In the future, when seeking a regex-based solution, you will receive higher quality answers when you supply at least 2 or 3 different realistic inputs to test against.

(Pattern Demo)
Code (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
Sign up to request clarification or add additional context in comments.

2 Comments

My code using preg_match_all, but i cant not find right regex way then i donot post my code. Thank your help but have some little bug when have neasted-shortcode and multi attribute like $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_3 attr_43="test43"][code_4_4 attr_43="test44"]Here44[/code_4_4][/code_4_3] [/code_4]';
@DeLe It's like I predicted this outcome. I cannot read minds. I can only write solutions using the posted question information. Please take a few days to try to understand my answer and make adaptations.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.