2013-02-04 77 views
2

在PHP中我有一些字符串標籤(僞代碼):更換嵌套支架對

[TAG_A] and [TAG_B] are connected with [TAG_[TAG_A]] 

它應該:

[TAG_A]    = X 
[TAG_B]    = Y 
[TAG_X]    = Z 

所以當我在一個字符串替換這些標籤輸出:

X and Y are connected with Z 

問題在於嵌套標籤。它需要遞歸,首先替換內部標籤。所有可能的標籤(及其值)都存儲在一個大型數組中。

我想要一個替換方法,不僅僅使用暴力替代標籤數組上使用foreach所有標籤,但實際上只在字符串中搜索[]對,然後查找標籤陣列。

我認爲正則表達式並不是正確的方式,但是做這種事情的最有效方法是什麼?

+0

對我來說,正則表達式是正確的方式。你知道你可以給preg_replace模式和替換爲數組嗎?然後做一個循環,直到沒有被替換。 – palindrom

回答

1

替換字符串中的標籤,然後檢查過程後是否出現新標籤。再次運行代碼,直到沒有更多標籤被替換。

$string = '[TAG_A] and [TAG_B] are connected with [TAG_[TAG_A]]'; 
$search = array(
    '[TAG_A]' => 'X', 
    '[TAG_B]' => 'Y', 
    '[TAG_X]' => 'Z' 
); 
$continue = true; 
while ($continue) { 
    foreach ($search as $find => $replace) { 
     $string = str_replace($find, $replace, $string); 
    } 
    $continue = false; 
    foreach ($search as $find => $replace) { 
     if (strpos($string, $find) !== false) { 
      $continue = true; 
      break; 
     } 
    } 
} 
echo $string; // prints "X and Y are connected with Z" 

正則表達式的解決方案:

$string = '[TAG_A] and [TAG_B] are connected with [TAG_[TAG_A]]'; 
$search = array(
    'TAG_A' => 'X', 
    'TAG_B' => 'Y', 
    'TAG_X' => 'Z' 
); 
while(preg_match_all('/\[([^\[\]]*?)\]/e', $string, $matches)) { 
    $string = preg_replace('/\[([^\[\]]*?)\]/e', '$search["$1"]', $string); 
} 
echo $string; 
+0

'這些標籤實際上是一個大陣列。「我剛剛讀過這個。不知道這是否有幫助。 – Antony

+0

好吧,這可以工作,但也許它不會很有效。我相信這也不適用於三重或四重嵌套標籤。 – Dylan

+0

@Dylan它適用於「三重或四重嵌套標籤」。我剛剛測試過它。 – Antony