Search code examples
phpregexpreg-replacepreg-match

php preg_replace ignore class attribute if not exist


hello I have the following code :

$content1 = '<img src="image1.png" class="image1"><img src="image2.png"><img src="image3.png" class="image3">';

when I use this code :

preg_replace('~<img\s*.*?\s*class\s*=\s*"([^"]*)"\s*.*?>~i','<img src="image-replaced" class="$1">', $content1);

this is what I get :

<img src="image-replaced" class="image1"><img src="image-replaced" class="image3">

as you can see this <img src="image2.png"> got ignored because it doesn't have a class attribute so it didn't get replaced.
now what I want to do is if img tag has class attribute in it then it get replaced if not then replace it and keep class blank like this:

<img src="image2.png" class="">

I appreciate any help from you.


Solution

  • Instead of using regular expression, you may consider using DOM for this.

    $doc = new DOMDocument;
    @$doc->loadHTML($content1); // load the HTML data
    
    $imgs = $doc->getElementsByTagName('img');
    
    foreach ($imgs as $img) {
      if ($img->hasAttribute('class')) {
          $img->setAttribute('src', 'image-replaced');
      } else {
          ## Otherwise set an empty class if you desire. 
          $img->setAttribute('class', '');
      }
    }
    

    If you must use regular expression, I would consider using a callback:

    $str = preg_replace_callback('~<img src="([^"]*)"(?: class="([^"]*)")?>~i', 
      function($m) {
        return '<img src="'.(isset($m[2])?'image-replaced':$m[1]).'" class="'.($m[2]?:'').'">';
      }, $str);
    

    eval.in