How to replace each occurrence of a regular expression match with a different value?

Asked

Viewed 181 times

4

I have a text (html code) with several images in standard HTML format:

<img src="X" atributos />

I need the value of the attribute src is replaced by the identifier CID:# where # is a unique value that identifies each image (see code below). That is, each image will have a different value within that attribute.

Below the code I’ve done so far, it already matches the images correctly. But how to make this replacement?

Other important information is that I need to have in the code the information of which unique identifier replaced which value (image url) of the attribute src. For example, I need to have a way of knowing that the 354 identifier replaced the value "img/xxx.jpg".

preg_match_all('/<img src=[",\']([^>,^\',^"]*)[",\']([^>]*)/', $html, $matches);

$url_imagem = array();
$atributos_imagem = array();
$cid = array();
$contador = 0;

foreach ($matches[1] as $i => $img){

    $url_imagem[$contador] = $matches[2][$i];
    $atributos_imagem[$contador] = $matches[3][$i];

    //Como substituir o conteudo do atributo SRC com o valor da variável $cid abaixo?
    $cid[$contador] = "CID:".date('YmdHms').'.'.time();

    $contador++;   
}
  • The srcthe images are different?

  • I have no control over the content of srcs. So they can be equal or different

1 answer

4


First this $contador = 0; is unnecessary in the foreach, since the variable $i already returns the indexes starting from 0, that is, where you use $contador can be replaced by $i.

Another problem is the amount you’re using date and hours:

$cid[$i] = "CID:".date('YmdHms').'.'.time();

In this way all the values of $cid[$i] will have the same value because the loop will run in a way that does not differentiate the time of the system. This means that with each loop in the loop, the time will be the same and if it is to replace the srcimages, all will have the same value.

To make sure that each value will be different, you can add another unique value, the $i:

                                     concatenar o $i
                                            ↓
$cid[$i] = "CID:".date('YmdHms').'.'.time().$i;

And finally, to make the substitution, you can use the preg_replace replacing the first occurrence:

$html = preg_replace('/'.$img.'/', $cid[$i], $html, 1);

I also created an array $identificador = array(); to store the srcreplaced so that you can know which were and in which sequence.

Example:

Initial images:

$html = '<img src="link1" atributos />
<img src="link2" atributos />
<img src="link1" atributos />';

Note that the 3rd image has the same src of the 1st. After the replacement, it will be something like this:

                                                ↓
$html = '<img src="CID:20180627170651.15301318110" atributos />
<img src="CID:20180627170651.15301318111" atributos />
<img src="CID:20180627170651.15301318112" atributos />';
                                       ↑

See in the arrows that the $i makes one value different from the other.

The code would look like this:

preg_match_all('/<img src=[",\']([^>,^\',^"]*)[",\']([^>]*)/', $html, $matches);

$url_imagem = array();
$atributos_imagem = array();
$cid = array();
$identificador = array();

foreach ($matches[1] as $i => $img){

    $url_imagem[$i] = $matches[1][$i];
    $atributos_imagem[$i] = $matches[2][$i];

    //Como substituir o conteudo do atributo SRC com a variável $cid abaixo?
    $cid[$i] = "CID:".date('YmdHms').'.'.time().$i;
    $tag_img = str_replace("/", "\/", $img);    
    $html = preg_replace('/'.$tag_img.'/', $cid[$i], $html, 1);
    $identificador[$i] = $img;

}
  • Thank you for the answer! The problem is that I cannot consider that srcs will necessarily be different.

  • One idea would be to try to use the $i to replace the $i th occurrence, replacing exactly the current src, but I could not do.

  • I get it... I’ll review it here...

  • I updated the answer. The correct one would be to use preg_replace replacing the first occurrence. So it replaces in the sequence, no matter if there are images with the same src.

  • Excellent answer! It worked, thank you!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.