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


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

<img src="X" atributos />

I need the value of the src attribute to be 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 is the code I've done so far, it already matches the images correctly. But how to make this replacement?

Another important piece of information is that I need to have in the code the information of which unique identifier replaced which value (image url) of the src attribute. For example, I need a way to know that the identifier 354 has 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();



First this $contador = 0; is unnecessary in foreach , since the $i variable already returns the indices starting from 0 , that is, where you use $contador can replace it with $i .

Another problem is the amount you are getting using date and time :

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

This way all values ​​of $cid[$i] will have the same value because the loop will run in a way that doesn't differentiate the system time. This means that each loop around, the time will be the same and if you replace the src s of the images, they will all have the same value.

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

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

And finally, to do the replacement, you can use preg_replace replacing the first occurrence:

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

I also created an array $identificador = array(); to go storing the replaced src s so that you can know which were and in which sequence.


Initial images:

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

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

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

See on the arrows that $i makes one value different from another.

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;

Scroll to Top