Use preg_match_all and str_replace to replace HTML content in PHP

In this post, I’m going to dive into the weird and wacky world of Regular Expressions to breakdown how to replace the contents of an HTML string using PHP. 

For example, we are going to start with something like:

$oldHTML = <div class=“some-class”>Some data</div>

and by the end it will be 

<div class=“some-class some-additional-class”>Some data plus some additional data</div>

To do so, we’ll need to begin by identifying the portion of the HTML that we need to replace. To do so we’ll use a preg_match_all

$content = ‘/<div class=“some-class”>(.*?}<\/div>/‘:

The (.*?) between the div tags ensures that we’ll be able to find any content that matches the HTML class pattern, enabling us to replace multiple matches in the same function. Next, we’ll call preg_match_all on our content to capture the matches. 

preg_match_all($content, $startingHTML, $matches, PREG_OFFSET_CAPTURE);

After running this line, $matches is now an array and will now take on a data structure to the effect of this: 

0 => array:2 [▼
    0 => array:1 [▼
        0 => "<div class=“some-class”>Some data</div> ◀"
    ]
    1 => array:1 [▼
        0 => "<div class=“some-class”>Some more data</div>◀”
    ]
  ]
]

Now that we’ve got an array of matches, let’s loop over each one to perform whatever it is we need to do to this HTML. 

$numberOfMatches = count($matches[0]);

for ($i = 0; $i < $numberOfMatches; $i++;) { 
    // here we will replace the HTML 
    // I did it using Laravel’s render method, but use the solution that works for you 
    $newHTML = view(‘partials.data’, $matches)->render();
}

Finally, let’s end the process by running a string replace over each match, replacing $oldHTML with $newHTML. We will use our array structure to make sure we target the proper portion of the $matches.

for ($i = 0; $i < $numberOfMatches; $i++;) { 
    $newHTML = view(‘partials.data’, $matches)->render();
    $replacedHTML = str_replace($matches[0][$i], $newHTML, $oldHTML);
}

At this point we have successfully replaced our initial HTML with some new rendered HTML. Any questions, let me know in the comments below!