Reputation: 51715
Let's say I have a string
This $0 is $2 $1. Still, \$$3 is a lot to pay for a puppy.
and an array of replacements
array('puppy', 'cute', 'ridiculously', '1300')
What would be the cleanest way to replace the tokens in the string with the corresponding items in the array, letting me backslash-escape the token character (in this case $
)? I also want to replace unmatched tokens with the empty string.
Upvotes: 1
Views: 5825
Reputation: 1186
This solution follows the question and borrows a little from Josh Leitzel's answer. Unmatched patterns (eg. $4, $5) are replaced by an empty string, removing them from the input.
$input = "This $0 is $2 $1. Still, \$$3 is a lot to pay for a puppy.";
$replacements = array('puppy','cute','ridiculously','1300');
$pattern = "/[$]{1}([0-9]{1})/";
preg_match_all($pattern, $input, $matches);
if (isset($matches[1]))
foreach ($matches[1] as $key => $value)
{
$input = str_replace("$".$value, $replacements[$value], $input);
}
echo $input;
Output:
This puppy is ridiculously cute. Still, $1300 is a lot to pay for a puppy.
Upvotes: 0
Reputation: 53940
i guess you meant "\$3", not "\$$3"
preg_replace('~(?<!\\\\)\$(\d+)~e', 'isset($array[$1])?$array[$1]:""', $source);
btw, did you know that sprintf allows numbered params as well (http://php.net/manual/en/function.sprintf.php example 3)
Upvotes: 1
Reputation: 625237
Here's one version.
$replacements = array('puppy', 'cute', 'ridiculously', '1300');
$input = 'This $0 is $2 $1. Still, \$3 is a lot to pay for a puppy.';
$output = preg_replace_callback('/(?<!\\\\)\$(\d+)/', 'replace_input', $input);
echo $input . "<br>";
echo $output;
function replace_input($matches) {
global $replacements;
$index = $matches[1];
return $index < 0 || $index >= count($replacements) ? $matches[0] : $replacements[$index];
}
Output:
This $0 is $2 $1. Still, \$3 is a lot to pay for a puppy.
This puppy is ridiculously cute. Still, \$3 is a lot to pay for a puppy.
It handles a backslash before the $ to escape that variable. That could be an awkward syntax because then you need to escape backslashes, which complicates it further (and isn't handled in this case). The regular expression basically means $ followed by one or more digits as long as the $ isn't preceded by a backslash (using a negative lookbehind).
It uses a global for the replacements array. There are two alternatives to this:
create_function()
.But I think the global is simpler and "global" unless you have a good reason to do something different in spite of the usual distaste we have for such things.
Upvotes: 1
Reputation: 574
$test_sub= 'This $0 is $2 $1. Still, \$$3 is a lot to pay for a puppy.';
$GLOBALS['replacers'] = array('puppy', 'cute', 'ridiculously', '1300');
echo preg_replace_callback('/[^\$]\$([0-9])+/',
create_function(
'$matches',
'return $matches[0][0] . $GLOBALS[\'replacers\'][$matches[1]];'
),
$test_sub
);
This is a POC of how it can be done. A simple regular expression and a callback for replacement. The actual implementation varies on what exactly you want to do with it. I hope it helped.
Upvotes: 1
Reputation: 15209
foreach ($array AS $key => $value)
{
$string = str_replace('$' . $key, $value, $string);
}
Upvotes: 4