Search code examples
phparraysforeachstr-replace

Replace all strings from an array of strings won't work


I have the following string

$content = '[tab title="Tab A" content="Tab a content."][tab title="Tab B" content="Tab B content"][tab title="Tab C" content="Tab C content"]';

Now I want to split the content like so:

$contentID = preg_split('/(\]\[)|(\]\s*\[)/', $content);

So far so good, now I need to check if each string of the $contentID array contains the id= part so I can add it if missing:

// set a new array
$newContentID = array();
// set a unique ID
$id = 'unique';

// include an id attribute for each string part
foreach ( $contentID as $i => $tabID ) {
 $newContentID[$i] = !strpos( $tabID, 'id=' ) === true ? str_replace( '[tab', '[tab id="'.$id.'-'.$i.'"', $tabID) : $tabID;
}

In the end I just implode all contents into the same $content array.

$content = implode('][',$newContentID);

The contents of the new #content goes like this:

var_dump($content);

/////////////// RESULT ///////////////////
string "[tab id="unique-0" title="Tab A" content="Tab a content."][tab title="Tab B" content="Tab B content"][tab title="Tab C" content="Tab C content"]"


var_dump($contentID);

/////////////// RESULT ///////////////////

array(3) {
  [0]=>
  string(13) "
[tab id="tab-a" title="Tab A" active="1" content="Tab a content""
  [1]=>
  string(13) "tab id="tab-b" title="Tab B" content="Tab B content""
  [2]=>
  string(13) "tab id="tab-c" title="Tab C" content="Tab C content."]
"
}

Why doesn't foreach do what I'm expecting it to do (to add id in each string part where missing)? How can I solve this?


Solution

  • The id part is not being added because the result of the preg_split is:

    array(3) {
      [0]=>
      string(43) "[tab title="Tab A" content="Tab a content.""
      [1]=>
      string(41) "tab title="Tab B" content="Tab B content""
      [2]=>
      string(42) "tab title="Tab C" content="Tab C content"]"
    }
    

    This means that the str_replace('[tab', '[tab id="'.$id.'-'.$i.'"', $tabID) on the foreach is not going to work because for the array indexes (1, 2) there is no string [tab to be replaced.

    A workaround is to check if [tab exists with the strpos function like this:

    $content = '[tab title="Tab A" content="Tab a content."][tab title="Tab B" content="Tab B content"][tab title="Tab C" content="Tab C content"]';
    
    $contentID = preg_split('/(\]\[)|(\]\s*\[)/', $content);
    
    // set a new array
    $newContentID = array();
    // set a unique ID
    $id = 'unique';
    
    // include an id attribute for each string part
    foreach ( $contentID as $i => $tabID ) {
     $newContentID[$i] = strpos($tabID, 'id=') === false ? addId($tabID, $id, $i) : $tabID;
    }
    
    $content = implode('][',$newContentID);
    
    function addId($tabID, $id, $i) {
        if (strpos($tabID, '[tab') === 0) {
            return str_replace('[tab', '[tab id="'.$id.'-'.$i.'"', $tabID);
        } else if (strpos($tabID, 'tab') === 0) {
            return 'tab id="' . $id . '-' . $i . '"' . substr($tabID, 3);
        }
    }
    

    The result of echo $content:

    [tab id="unique-0" title="Tab A" content="Tab a content."][tab id="unique-1" title="Tab B" content="Tab B content"][tab id="unique-2" title="Tab C" content="Tab C content"]