Как заменить переменную в строке со значением в php?

У меня есть строка, подобная этой в базе данных (фактическая строка содержит 100 слов и 10 переменных)

i am a {$club} fan 

Я повторяю эту строку следующим образом

  $club = "Barcelona"; echo $data_base[0]['body']; 

Мой результат: i am a {$club} fan . Я хочу, чтобы i am a Barcelona fan Как я могу это сделать?

Использовать strtr Он будет переводить части строки.

 $club = "Barcelona"; echo strtr($data_base[0]['body'], array('{$club}' => $club)); 

Для нескольких значений ( Demo ):

 $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. 
 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, поэтому я мог видеть, как я набираю, если мое выражение будет работать. У меня есть переменные, которые мне нравятся в моих выражениях, поэтому мне не нужно повторно указывать один и тот же бит для каждого выражения.

Я бы предложил функцию sprintf() .

вместо хранения i am a {$club} fan использую i am a {$club} fan i am a %s fan , поэтому ваша команда эха будет выглядеть так:

 $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

 /** * 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.' '); } 

То, что вы ищете, это вложенная строковая интерполяция. Теорию можно прочитать на этом посту: 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; 

вот мое решение:

 $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); } 

Вы можете использовать простой синтаксический анализатор, который заменяет {$ 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); } 

Попробуйте preg_replace php preg_replace .

http://php.net/manual/en/function.preg-replace.php

 <?php $club = "barcelona"; echo $string = preg_replace('#\{.*?\}#si', $club, 'i am a {$club} fan'); ?> 

Что-то вроде этого должно решить вашу проблему:

 $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"; 

Обратите внимание, что это использует взлом импорта всех глобальных переменных. Это может быть не совсем то, что вы хотите. Вероятно, использование замыканий было бы лучшей идеей.

вы можете использовать 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