Reputation: 11448
If I have a string, and I search in the string for a particular text after a signal, is there any way to output the text string with the particular text after the signal replaced with a variable of the same name?
Example
I have
$strin="This is #fruit"
$fruit="omg"
So I search $strin, extract "fruit" using regex, then replace #fruit with the value of $fruit.
Any ideas how to do this in PHP?
Edit - It may not always be fruit. There is basically a set of #things and $variablesofthethings. So it will not always be fruit. But every #things will have a $variablesofthings. So, I don't know what the thing will be but I know there is a variable for it with the same name. hope this makes sense!
Upvotes: 1
Views: 390
Reputation: 99921
If you have a single variable to replace, you can use this simple regex:
$text = preg_replace('/#fruit\b/', $fruit, $string);
The \b
after #fruit
ensures that we don't accidentally replace #fruit2
for example.
If you have multiple variables to replace, you can replace them all at once with preg_replace_callback:
$vars = array(
'fruit' => 'apple',
'color' => 'red',
);
$text = preg_replace_callback('/#(\w+)\b/', function($match) use ($vars) {
if (isset($vars[$match[1]])) {
return $vars[$match[1]];
} else {
return $match[0];
}
}, $string);
The regex will match any # followed by letters and numbers and _ (the \w
matches [a-zA-Z0-9_]
). For each match, if a variable with that name exists in $vars, it gets replaced by the variable value.
If you want to replace the variables with true PHP variables (e.g. replace #fruit
with the value of $fruit
), set $vars
to $GLOBALS
:
$vars = $GLOBALS;
But don't do that. If the string comes from users, they will be able to get the value of any of your variables.
The previous solution uses a closure, so you need PHP 5.3 to execute it.
If you don't have PHP5.3 you can do the same with this:
class Replacer {
private $vars = array(
'fruit' => 'apple',
'color' => 'red',
);
function replace($match) {
if (isset($this->vars[$match[1]])) {
return $this->vars[$match[1]];
} else {
return $match[0];
}
}
}
$text = preg_replace_callback('/#(\w+)\b/', array(new Replacer, 'replace'), $string);
Why using a class for this ? This way the function can access $this->vars
, this avoids using a global variable.
If you are trying to insert variables inside of string literals, PHP can do it for you:
$fruit = 'apple';
$string = "The fruit is: $fruit";
When you use double quotes to enclose your strings, PHP recognizes variables and replace them automatically.
Upvotes: 0
Reputation: 8855
You could use variable variables in PHP to have your value, and then use PHP built-int string interpolation to place the value of the variable in the string. this way your variable names could be dynamic too.
Variable Variables: in PHP you could have a variable like this:
$fruit = 'apple';
$car = 'toyota';
But you could have a variable, whose name is detected from another variable. like this:
$$name;
This references to the variable whose name is the value of the variable $name. So for example if you receive the value of variable $name from the CLI arguments:
$name = $argv[1];
Then if the user enters 'fruit' in the command line, your variable $name would have the value of 'fruit', and then $$name would refer to the variable named $fruit with the value of 'apple'.
$$name; // --> 'apple'
now you could use PHP interpolation (in strings enclosed by double quotes) to replace the variable, with its value:
echo "I have a $$name"; // --> I have a apple.
Here is completed example of how to do this:
$father = "John";
$mother = "Marta";
$brother = "Henry";
$relative = $$argv[1]; // or you could read the relative from any source
echo "I love $relative";
Upvotes: 1
Reputation: 169018
If your goal is to find #x
tokens and replace them with the value of $x
, you can do something like this:
$strin = preg_replace_callback('/#([a-zA-Z_][a-zA-Z0-9_]*)/', function($match) {
$varname = substr($match, 1);
global $$varname;
return $$varname;
}, $strin);
However, if this is going to be evaluating a user-supplied string, you'd be better off throwing all of the possible substitutions in an associative array. This is for security reasons (you don't want some web user to be able to see all of your global variables, do you?). Example:
$tokens = array('fruit' => 'omg');
$strin = preg_replace_callback('/#([a-zA-Z_][a-zA-Z0-9_]*)/', function($match) {
$token = substr($match, 1);
return $tokens[$token];
}, $strin);
Upvotes: 2
Reputation: 1907
No need to use regex here, you can use str_replace
:
$result = str_replace("#fruit", $fruit, $strin);
Upvotes: 4