phpshortcodebbcode

Parse BBCode in array


I am trying to call a function from BBCode(like WordPress shortcodes). but I didn't find any code to do that, only I found HTML tag parser like:

[bold]Bold text[/bold]
->
<b>Bold text</b>

But I want to save it as an array, for example:

[date format="j M, Y" type="jalali"]

to something like this:

array(
    'date' => array(
        'format' => 'j M, Y',
        'type' => 'jalali'
    )
)

*Edited

I made a code to do this (sorry if my English is bad):

[date format="Y/m/d" type="jalali"] =>

Step 1: Get code between "[" and "]":
date format="Y/m/d" type="jalali"

Step 2: Explode space in the code:
$code = array('date', 'format="Y/m/d"', 'type="jalali"')

Step 3: Get shortcode name(offset 0 of $code) and get
difference($code excluded offset 0):
$name = 'date'
$attr = array('format="Y/m/d"', 'type="jalali"')

Step 4: Now I have attributes and code name. But the problem is if
put space in attributes value it will explode that too:
[date format="j M, Y" type="jalali"] =>
$code = array('date', 'format="j', 'M,', ' Y"', 'type="jalali"');

Now how can I fix this or get name and attributes with regex or anything else?


Solution

  • You can try this using regex

    $code = '[date format="j M, Y" type="jalali"]';
    
    preg_match_all("/\[([^\]]*)\]/", $code, $matches);
    
    $codes = [];
    
    foreach($matches[1] as $match) {
      // Normalize quotes into double quotes
      $match = str_replace("'",'"',$match);
      // Split by space but ignore inside of double quotes
      preg_match_all('/(?:[^\s+"]+|"[^"]*")+/',$match,$tokens);
      $parsed = [];
      $prevToken = '';
      foreach($tokens[0] as $token) {
        if(strpos($token,'=') !== false) {
          if($prevToken !== '') {
            $parts = explode('=',$token);
            $parsed[$prevToken][$parts[0]] = trim($parts[1],'"\''); 
          }
        } else {
          $parsed[$token] = [];
          $prevToken = $token;
        }
      }
    
      $codes[] = $parsed;
    }
    
    var_dump($codes);
    

    Result:

    array(1) {
      [0]=>
      array(1) {
        ["date"]=>
        array(2) {
          ["format"]=>
          string(6) "j M, Y"
          ["type"]=>
          string(6) "jalali"
        }
      }
    }