我在數據庫中的字符串是這樣的(實際的字符串包含字的100S和可變的10S)如何用PHP中的值替換字符串中的變量?
i am a {$club} fan
我贊同這個字符串像這樣
$club = "Barcelona";
echo $data_base[0]['body'];
我的輸出爲i am a {$club} fan
。 我想要i am a Barcelona fan
我該怎麼做?
我在數據庫中的字符串是這樣的(實際的字符串包含字的100S和可變的10S)如何用PHP中的值替換字符串中的變量?
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.
我的字符串包含20個像這樣的變量。需要我使用str_replace()fn 20次? – 2013-02-25 11:04:38
這將是簡單的出路。您也可以使用關聯數組和循環的組合。看到我上面的代碼。 – Husman 2013-02-25 11:07:56
@messifan使用此解決方案時,請務必記得每次將另一個變量添加到模板時更新您的聯想數組。 – 2013-02-25 11:27:41
像這樣的東西應該解決您的問題:
$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";
請注意,這使用導入所有全局變量的黑客。這可能不是你想要的。可能使用閉包將是一個更好的主意。
eval是一個非常糟糕的建議 – David 2013-02-25 11:14:05
@David:我知道,這就是我爲什麼寫這是一件壞事。 – 2013-02-25 11:20:11
如果這是一件不好的事情,甚至發佈它有什麼意義?或者,也許它應該是一個評論,而不是一個答案。 – 2013-02-25 11:29:12
您可以使用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
剛剛在串上試過你的代碼_I是{club} fan_(沒有'$'符號) - 得到了以下結果:** PHP致命錯誤:當不在第3行的/tmp/p.php中的對象上下文中時使用$ this ** – 2013-02-25 11:25:19
@AleksG我在回答這段代碼是爲了上課你不能在課堂上使用它 – 2013-02-25 11:26:57
我已經破解了你的代碼,並且我遇到的問題是像$ club這樣定義的變量出來了回調函數的範圍,所以我最終得到'未定義的變量:$ club' – 2013-02-25 11:27:34
嘗試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');
?>
但是這將取代所有的變數與$俱樂部 – 2013-02-25 11:17:47
@JacobTomlinson是的,它會.. – 2013-02-25 11:18:28
@Dipesh OP需要用它的相應值替換每個變量。你顯然誤解了這個問題。 – 2013-02-25 11:22:20
你在找什麼是嵌套的串插。一個理論可以在這篇文章中閱讀: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;
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編寫了自己的正則表達式測試程序,所以我可以看到,如果我的表達式要工作,就可以輸入。我有我喜歡在我的表達式中使用的變量,以便我不需要爲每個表達式重新輸入相同的位。
/**
* 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.' ');
}
不使用全局變量的最佳解決方案。謝謝! – WillianLKeller 2016-05-19 02:21:34
這裏是我的解決方案:
$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);
}
我建議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風扇
你可以使用一個簡單的解析器,如果它存在,它將使用映射中的值替換{$ 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);
}
[str_replace()函數(http://php.net/manual/en/function.str-replace.php) – Eggplant 2013-02-25 11:00:32
我的字符串包含20變量這樣。需要我使用str_replace()fn 20次? – 2013-02-25 11:06:28
preg_replace是你在找什麼。 – 2013-02-25 11:07:53