preg-replacepreg-replace-callback

Replace preg_replace with preg_replace_callback due to e modifier deprecation


Get a warning because the e modifier deprecation on preg_replace function. Here is the code, I suggest that should be replaced by preg_replace_callback function (for php 7.4.16) :

`$text = preg_replace("#\[img\]((http|ftp|https|ftps)://)([^ \?&=\#\"\n\r\t<]*?(\.(jpg|jpeg|gif|png)))\[/img\]#sie", "'[img:$uid]\\1' . str_replace(' ', '%20', '\\3') . '[/img:$uid]'", $text);`

I've been trying to fix it for a while now but cannot seem to get it to work, so any assistance will be highly appreciated.

I couldn't apply the logic explained here: https://stackoverflow.com/questions/15454220/replace-preg-replace-e-modifier-with-preg-replace-callback


Solution

  • This part in the code would not replace anything str_replace(' ', '%20', '\\3') as the group 3 value has a negated character class that does not match a space.

    For the replacement of a space to %20 you could just use a single capture group denoted by $m[1] in the example code, instead of the multiple capture groups that are in the current pattern.

    There are a few superfluous escapes in the pattern, and you might shorten [^ \n\r\t] to [^\s]

    If you want to use $uid in the callback function, you can write it like use ($uid)

    As the e flag is deprecated, and you are not using a dot so you can omit the s flag, you only need the i flag for a case insensitive match.

    If you are not matching any spaces, you could use preg_replace_callback for example like this:

    $text = "[img]http://www.test.com/abc.jpg[/img]";
    $uid = 123;
    
    $text = preg_replace_callback(
        "#\[img]((?:https?|ftps?)://[^\s?&=\#\"<]*?\.(?:jpe?g|gif|png))\[/img]#i",
        function ($m) use ($uid) {
            return "[img:$uid]" . $m[1] . "[/img:$uid]";
        },
        $text
    );
    
    echo $text;
    

    Output

    [img:123]http://www.test.com/abc.jpg[/img:123]
    

    See a regex demo and a PHP demo


    If you are matching any spaces, you might omit \s from the negated character class:

    $text = "[img]http://www.test.com/  abc.jpg[/img]";
    $uid = 123;
    
    $text = preg_replace_callback(
        "#\[img]((?:https?|ftps?)://[^?&=\#\"<]*?\.(?:jpe?g|gif|png))\[/img]#i",
        function ($m) use ($uid) {
            return "[img:$uid]" . str_replace(' ', '%20', $m[1]) . "[/img:$uid]";
        },
        $text
    );
    
    echo $text;
    

    Output

    [img:123]http://www.test.com/%20%20abc.jpg[/img:123]
    

    See a regex demo and a PHP demo