2014-09-24 253 views
0
$message = "[Link] Thanks [Link]"; 
echo str_replace(
array("[Link]", "[Link]"), 
array("mylink1", "mylink2"), 
$message 
); 

打印一個字符串:「mylink1感謝mylink1」替換多個字符串

但是,我想打印「mylink1感謝mylink2」

什麼是這樣做的正確方法?

回答

3

您可以使用此函數作爲代碼中的插入替換。如@ h2ooooooo所示,它使用vsprintf。我之前的版本失敗了,因爲我以錯誤的方式使用str_replace的參數$count

function str_replace_array($search, array $replace, $subject) 
{ 
    return vsprintf(
     str_replace('[Link]', '%s', $subject), 
     $replace); 
} 

$message = "[Link] Thanks [Link]"; 
echo str_replace_array(
    "[Link]", 
    array("mylink1", "mylink2"), 
    $message 
); 
+0

哇。在這裏我正在考慮正則表達式組。做得很好。 – MoshMage 2014-09-24 10:11:26

+0

這是一個很好的解決方案,但是您應該添加一個額外的'str_replace('%','%%',$ subject)'來轉義消息中的'%'。 – Gellweiler 2014-09-24 18:16:29

+0

如果它們來自外部,你應該用替換中的'%%'替換'%'。 – Gellweiler 2014-09-24 18:38:44

3

也許您正在尋找sprintf

$message = "%s Thanks %s"; 
echo sprintf($message, "mylink1", "mylink2"); // mylink1 Thanks mylink2 

DEMO


如果您更喜歡使用數組(動態變量很有用),還有vsprintf

$message = "%s Thanks %s"; 
echo vsprintf($message, array("mylink1", "mylink2")); // mylink1 Thanks mylink2 

DEMO


如果你真的希望不使用sprintfvsprintf,你可以使用preg_replace的第四個參數(limit)爲「1」(只在你找到的第一個匹配時才這樣做)。請確保您有preg_quote所以.+*等使用它沒有什麼特別的含義:

<?php 

function smartReplace($search, $replace, $subject) { 
    if (!is_array($search)) { 
     throw new Exception('$search must be an array'); 
    } 

    if (!is_array($replace)) { 
     throw new Exception('$replace must be an array'); 
    } 

    if (!is_string($subject)) { 
     throw new Exception('$subject must be a string'); 
    } 

    for ($i = 0, $len = count($search); $i < $len; $i++) { 
     $subject = preg_replace('/' . preg_quote($search[$i], '/') . '/', $replace[$i], $subject, 1); 
    } 

    return $subject; 
} 

$message = "[Link] Thanks [Link]"; 

echo smartReplace(
    array("[Link]", "[Link]"), 
    array("mylink1", "mylink2"), 
    $message 
); // mylink1 Thanks mylink2 

DEMO

+0

我糾正了[我的答案](http://stackoverflow.com/a/26014204/511529),所以它使用你的。 – GolezTrol 2014-09-24 10:20:31

0

可以使用preg_replace而不是str_replace設置限制

$message = "[Link] Thanks [Link]"; 
$replacements = array ("Link 1", "Link 2"); 
while (!empty($replacements)) { 
    $replacement = array_shift($replacements); 
    $message = preg_replace("/\[Link\]/", $replacement, $message, 1); 
} 
echo $message; 

輸出:

鏈接1個由於連接2

+0

只是一個側面說明,雖然這在大多數情況下都能正常工作,但如果替換包含'[Link]',這將會產生問題。雖然在一般情況下這不是一個問題,但在某些特殊情況下這可能是一個潛在問題。 – Gellweiler 2014-09-24 18:14:02

+0

下面是一個例子:說你在一個在線編輯器中使用它,讓用戶添加鏈接到他們的消息。您運行過濾器來檢查鏈接是否不包含「XSS」(以便您的平臺不會成爲有效載荷的啓動板)。現在,攻擊者可以使用有效載荷URL中的[Link]在多個鏈路上分割有效載荷,並以這種方式欺騙你的過濾器。這種情況可能有點構建,但我認爲首先防止任何潛在的過濾器問題總是很聰明。 – Gellweiler 2014-09-24 18:33:14

0

一個簡單的方法是結合str_replacevsprintf

$message = "[Link] Thanks [Link]"; 
$template = str_replace("[Link]", "%s", $message); 
echo vsprintf($template, array("mylink1", "mylink2")); 
0

試試這個

$message = "[Link] Thanks [Link]"; 
echo preg_replace(array("/\[Link\]/", "/\[Link\]/"), 
array("mylink1", "mylink2"), 
$message, 1); 
+0

我認爲這會對OP和更多訪問者更有幫助,當你爲自己的意圖添加一些解釋。 – reporter 2014-09-24 10:55:34

0

使用vsprintf中可能是有害的,如果你可以在你的消息%。在將[Link]替換爲%s之前,您可以將所有出現的%替換爲%%,然後調用vsprintf。但我只想簡單地使用數組函數,這樣你就不必擔心正確轉義的字符。

function str_replace_array($message, $search, $replacements) 
{ 
    $result = ''; 

    $pieces = explode($search, $message); 
    $replace = reset($replacements); 
    foreach ($pieces as $i => $piece) { 
     if ($replace === FALSE) { 
      throw new Exception('There are not enough replacements for all occurences of the search string.'); 
     } 
     if ($i !== 0) { 
      $result .= $replace; 
      $replace = next($replacements); 
     } 
     $result .= $piece; 
    } 

    return $result; 
} 

echo str_replace_array('[Link] Thanks [Link]', '[Link]', array('mylink1', 'mylink2'));