Search code examples
phppreg-replaceenumerate

how to enumerate items with preg_replace?


I need to add some tags before and after images on document and numerate them at once. HTML Document code is:

....

<img src="http://img.example.com/img/mage1.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/image72.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/imagstr.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/image.jpg" alt="sometile"> <br> 
<img src="http://img.example.com/img/imgger.gif" alt="sometile"> <br> 
<img src="http://img.example.com/img/somepic.png" alt="sometile"> <br> 

I need in result code like this

<div><a name="#pic1"></a><img src="http://img.example.com/img/mage1.jpg" alt="sometile"></div>
<div><a name="#pic2"></a><img src="http://img.example.com/img/image72.jpg" alt="sometile"> </div> 
<div><a name="#pic3"></a><img src="http://img.example.com/img/imagstr.jpg" alt="sometile"> </div> 
<div><a name="#pic4"></a><img src="http://img.example.com/img/image.jpg" alt="sometile"> </div> 
<div><a name="#pic5"></a><img src="http://img.example.com/img/imgger.gif" alt="sometile"> </div> 
<div><a name="#pic6"></a><img src="http://img.example.com/img/somepic.png" alt="sometile"> </div> 

Solution

  • I'm not a fan of regex+HTML, but here goes (I just cooked up a simple regex—you probably already have one):

    $s = '<img src="http://img.example.com/img/mage1.jpg" alt="sometile"> <br> 
    <img src="http://img.example.com/img/image72.jpg" alt="sometile"> <br> 
    <img src="http://img.example.com/img/imagstr.jpg" alt="sometile"> <br> 
    <img src="http://img.example.com/img/image.jpg" alt="sometile"> <br> 
    <img src="http://img.example.com/img/imgger.gif" alt="sometile"> <br> 
    <img src="http://img.example.com/img/somepic.png" alt="sometile"> <br>';
    
    $i = 0;
    function wrap($s) {
            global $i;
            $i++;
            return sprintf('<div><a name="pic%d">%s</div>', $i, $s);
    }
    
    print preg_replace('#(<img [^>]+?>) <br>#e', "wrap('\\1')", $s);
    

    (Demo)

    The important part is the e modifier in the preg_replace(). See "Example #4 Using the 'e' modifier."


    EDIT
    As pointed out in the comments, $i is certainly not the best name for a global variable. If this is going to be used as a simple "one-off" transformation it may be alright. If not, change the name to something that will not conflict. Or put it as a public static in a class.

    Also, preg_replace_callback() exists. It's better suited, although I find the passing a function name as a string and evaluating functionName('arg') almost equally ugly :)