Как заменить переменную в строке со значением в php?
У меня есть строка, подобная этой в базе данных (фактическая строка содержит 100 слов и 10 переменных)
i am a {$club} fan
i повторяю эту строку следующим образом
$club = "Barcelona";
echo $data_base[0]['body'];
Мой вывод i am a {$club} fan
.
Я хочу i am a Barcelona fan
Как я могу это сделать?
Ответы
Ответ 1
Используйте strtr
Он преобразует части строки.
$club = "Barcelona";
echo strtr($data_base[0]['body'], array('{$club}' => $club));
Для нескольких значений (Демо):
$data_base[0]['body'] = 'I am a {$club} fan.'; // Tests
$vars = array(
'{$club}' => 'Barcelona',
'{$tag}' => 'sometext',
'{$anothertag}' => 'someothertext'
);
echo strtr($data_base[0]['body'], $vars);
Выход программы:
I am a Barcelona fan.
Ответ 2
/**
* A function to fill the template with variables, returns filled template.
*
* @param string $template A template with variables placeholders {$varaible}.
* @param array $variables A key => value store of variable names and values.
*
* @return string
*/
public function replaceVariablesInTemplate($template, array $variables){
return preg_replace_callback('#{(.*?)}#',
function($match) use ($variables){
$match[1]=trim($match[1],'$');
return $variables[$match[1]];
},
' '.$template.' ');
}
Ответ 3
Я бы предложил функцию sprintf()
.
вместо сохранения i am a {$club} fan
используйте i am a %s fan
, поэтому ваша команда echo будет выглядеть так:
$club = "Barcelona";
echo sprintf($data_base[0]['body'],$club);
OUTPUT: я поклонник Барселоны
Это даст вам свободу использования того же кода с любой другой переменной (и вам даже не нужно запоминать имя переменной).
поэтому этот код также действителен с той же строкой:
$food = "French Fries";
echo sprintf($data_base[0]['body'],$food);
OUTPUT: Я поклонник французского фриза
$language = "PHP";
echo sprintf($data_base[0]['body'],$language);
OUTPUT: я поклонник PHP
Ответ 4
То, что вы ищете, это вложенная строковая интерполяция. На этом посту можно прочитать теорию: http://thehighcastle.com/blog/21/wanted-php-core-function-for-dynamically-performing-double-quoted-string-variable-interpolation
Основная проблема заключается в том, что вы действительно не знаете все доступные переменные, или их может быть слишком много.
Рассмотрим следующий проверенный фрагмент кода. Я украл регулярное выражение от mohammad mohsenipur.
$testA = '123';
$testB = '456';
$testC = '789';
$t = '{$testA} adsf {$testB}adf 32{$testC} fddd{$testA}';
echo 'before: '.$t."\n";
preg_match_all('~\{\$(.*?)\}~si',$t,$matches);
if ( isset($matches[1])) {
$r = compact($matches[1]);
foreach ( $r as $var => $value ) {
$t = str_replace('{$'.$var.'}',$value,$t);
}
}
echo 'after: '.$t."\n";
Ваш код может быть:
$club = 'Barcelona';
$tmp = $data_base[0]['body'];
preg_match_all('~\{\$(.*?)\}~si',$tmp,$matches);
if ( isset($matches[1])) {
$r = compact($matches[1]);
foreach ( $r as $var => $value ) {
$tmp = str_replace('{$'.$var.'}',$value,$tmp);
}
}
echo $tmp;
Ответ 5
if (preg_match_all('#\$([a-zA-Z0-9]+)#', $q, $matches, PREG_SET_ORDER));
{
foreach ($matches as $m)
{
eval('$q = str_replace(\''.$m[0].'\',$'.$m[1].',$q);');
}
}
Это соответствует всем переменным $и заменяет их значением.
я не включил {}, но не должен быть слишком сложным, чтобы добавить что-то вроде этого...
if (preg_match_all('#\{\$([a-zA-Z0-9]+)\}#', $q, $matches, PREG_SET_ORDER));
{
foreach ($matches as $m)
{
eval('$q = str_replace(\''.$m[0].'\',$'.$m[1].',$q);');
}
}
Хотя это кажется немного медленнее, чем жесткая кодировка каждой переменной. И он представляет собой дыру в безопасности с eval. Вот почему мое регулярное выражение настолько ограничено. Чтобы ограничить объем того, что может хватить eval.
Я написал собственный тестер регулярных выражений с помощью ajax, поэтому я мог видеть, как я набираю, если мое выражение будет работать. У меня есть переменные, которые мне нравятся в моих выражениях, поэтому мне не нужно повторно указывать один и тот же бит для каждого выражения.
Ответ 6
Я нашел эти подходы полезными время от времени:
$name = 'Groot';
$string = 'I am {$name}';
echo eval('return "'.$string.'";');
$data = array('name' => 'Groot');
$string = 'I am {$data[name]}';
echo eval('return "'.$string.'";');
$name = 'Groot';
$data = (object)get_defined_vars();
$string = 'I am {$data->name}';
echo eval('return "'.$string.'";');
Ответ 7
вот мое решение:
$club = "Barcelona";
$string = 'i am a {$club} fan';
preg_match_all("/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/",$string,$matches);
foreach ($matches[0] as $key => $var_name) {
if (!isset($GLOBALS[$matches[1][$key]])) $GLOBALS[$matches[1][$key]] = 'default value';
$string = str_replace($var_name, $GLOBALS[$matches[1][$key]], $string);
}
Ответ 8
Вы можете использовать простой синтаксический анализатор, который заменяет {$ key} значение с карты, если оно существует.
используйте как $text = templateWith('hello $item}',array('item'=>'world'...));
Моя первая версия:
/**
* Template with a string and simple map.
* @param string $template
* @param array $substitutions map of substitutions.
* @return string with substitutions applied.
*/
function templateWith(string $template, array $substitutions) {
$state = 0; // forwarding
$charIn = preg_split('//u', $template, -1, PREG_SPLIT_NO_EMPTY);
$charOut = array();
$count = count($charIn);
$key = array();
$i = 0;
while ($i < $count) {
$char = $charIn[$i];
switch ($char) {
case '{':
if ($state === 0) {
$state = 1;
}
break;
case '}':
if ($state === 2) {
$ks = join('', $key);
if (array_key_exists($ks, $substitutions)) {
$charOut[] = $substitutions[$ks];
}
$key = array();
$state = 0;
}
break;
case '$': if ($state === 1) {
$state = 2;
}
break;
case '\\': if ($state === 0) {
$i++;
$charOut[] = $charIn[$i];
}
continue;
default:
switch ($state) {
default:
case 0: $charOut[] = $char;
break;
case 2: $key[] = $char;
break;
}
}
$i++;
}
return join('', $charOut);
}
Ответ 9
вы можете использовать preg_replace_callback для получения имени переменной, например
$data_base[0]['body'] = preg_replace_callback(
'#{(.*?)}#',
function($m) {
$m[1]=trim($m[1],'$');
return $this->$m[1];
},
' '.$data_base[0]['body'].' '
);
Внимание, этот код я написал для class($this);
, вы можете объявить переменную в класс. затем используйте этот код для определения переменной и замените их как
<?php
class a{
function __construct($array){
foreach($array as $key=>$val){
$this->$key=$val;
}
}
function replace($str){
return preg_replace_callback('#{(.*?)}#',function($m){$m[1]=trim($m[1],'$');return $this->$m[1];},' '.$str.' ');
}
}
$obj=new a(array('club'=>3523));
echo $obj->replace('i am a {$club} fan');
выход:
i am a 3523 fan
Ответ 10
Попробуйте preg_replace
функцию php.
http://php.net/manual/en/function.preg-replace.php
<?php
$club = "barcelona";
echo $string = preg_replace('#\{.*?\}#si', $club, 'i am a {$club} fan');
?>
Ответ 11
Что-то вроде этого должно решить вашу проблему:
$club = "Barcelona";
$var = 'I am a {$club} fan';
$res = preg_replace('/\{\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/e', "$$1", $var);
echo "$res\n";
Это однострочный preg_replace
.
Обновление: с модификатором php 5.5 /e
устарело. Вместо этого вы можете использовать обратный вызов:
$club = "Barcelona";
$var = 'I am a {$club} fan';
$res = preg_replace_callback('/\{\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/',
create_function(
'$matches',
'extract($GLOBALS, EXTR_REFS | EXTR_SKIP); return $$matches[1];'),
$var);
echo "$res\n";
Обратите внимание, что это использует взлом импорта всех глобальных переменных. Это может быть не совсем то, что вы хотите. Возможно, использование замыканий было бы лучшей идеей.