Search code examples
phpregexpreg-replacepreg-replace-callback

changing the replace value in preg_replace_callback


function replaceContent($matches = array()){
    if ($matches[1] == "nlist"){
        // do stuff
        return "replace value";
    } elseif ($matches[1] == "alist"){
        // do stuff
        return "replace value";
    }

    return false;
} 

preg_replace_callback('/<([n|a]list)\b[^>]*>(.*?)<\/[n|a]list>/','replaceContent', $page_content);

$matches in replaceContent() returns this array if matches are found:

Array
(
    [0] => <nlist>#NEWSLIST#</nlist>
    [1] => nlist
    [2] => #NEWSLIST#
)

Array
(
    [0] => <alist>#ACTIVITYLIST#</alist>
    [1] => alist
    [2] => #ACTIVITYLIST#
)

At the moment my preg_replace_callback function replaces the matches value with $matches[0]. What I am trying to do and wondering if even possible is to replace everything inside the tags ($matches[2]) and at the same time be able to do the $matches[1] check.

Test my regex here: http://rubular.com/r/k094nulVd5


Solution

  • You can simply adjust the return value to include the parts that you don't want to replace unchanged:

    function replaceContent($matches = array()){
        if ($matches[1] == "nlist"){
            // do stuff
            return sprintf('<%s>%s</%s>',
                           $matches[1],
                           'replace value',
                           $matches[1]);
        } elseif ($matches[1] == "alist"){
            // do stuff
            return sprintf('<%s>%s</%s>',
                           $matches[1],
                           'replace value',
                           $matches[1]);
        }
    
        return false;
    } 
    
    preg_replace_callback('/<([n|a]list)\b[^>]*>(.*?)<\/[n|a]list>/','replaceContent', $page_content);
    

    Note that:

    1. The pattern inside sprintf is produced based on the regex used for preg_replace_callback.
    2. If the replacement string needs to include more information from the original (e.g. possible attributes in the <nlist> or <alist> tags), you will need to get this data into a capture group as well so that it's available inside $matches.