0

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>

4
  • I wouldn't use $ as PHP already uses it for interpolation, it could lead to nasty bugs. Try using a different character, like test {#test} #test test Commented Jan 21, 2014 at 19:26
  • 1
    Also try putting your regex in single quotes if you use $. Commented Jan 21, 2014 at 19:30
  • That was it -- using single quotes around my regex. Can you write up an answer explaining why? Commented Jan 21, 2014 at 19:32
  • Nasty bug! Answer below is good, but my solution would be to just chose a different character. Commented Jan 21, 2014 at 19:33

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

I spotted that second problem after I submitted the question, and fixed by using $allVars[$match[1]] and adding parentheses in my regex: '/\$([a-zA-Z_][a-zA-Z0-9_]*)/' -- Thanks for an alternate solution, though!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.