Search code examples
phpregexpreg-replace-callback

simple regex isn't working using preg_replace_callback()


I'm trying to use preg_replace_callback to fill in variables in an imported document (which I control), based on this answer, but it's not working. As far as I can tell, the callback is never invoked, which would mean the regex is never being matched.

The bare-bones content of my doc.html file:

<p>test {$test} $test test</p>

The PHP:

$test = "ham";
$allVars = get_defined_vars();

$filename = "/path/to/doc.html";
$html = file_get_contents($filename);
$html = preg_replace_callback("/\$[a-zA-Z_][a-zA-Z0-9_]*/", "find_replacements", $html);

echo($html);
exit();

// replace callback function
function find_replacements($match) {
    global $allVars;
    if (array_key_exists($match[0], $allVars))
        return $allVars[$match[0]];
    else
        return $match[0];
}

The output is <p>test {$test} $test test</p>, but I was expecting <p>test {ham} ham test</p>


Solution

  • First, the dollar sign in regex is being interpolated by PHP because the regex is in double quotes. Put single quotes around that:

    $html = preg_replace_callback('/\$[a-zA-Z_][a-zA-Z0-9_]*/', "find_replacements", $html);
    

    Second, the values sent to your callback include the dollar sign, whereas the dollar sign is not present in the $allVars array, so you must manually strip it off:

    function find_replacements($match) {
        global $allVars;
        $match[0] = substr($match[0],1);
        if (array_key_exists($match[0], $allVars))
            return $allVars[$match[0]];
        else
            return $match[0];
    }
    

    Making those modifications, I was able to receive this output:

    test {ham} ham test