2013-03-06 84 views
1

好的,所以我的問題很簡單。我希望答案也是。 比方說,我有以下的PHP字符串:帶數組的preg_replace字符串

<!DOCTYPE html> 
<html> 
<head> 
    <title>test file</title> 
</head> 
<body> 
    <div id="dynamicContent"> 
     <myTag>PART_ONE</myTag> 
     <myTag>PART_TWO </myTag> 
     <myTag> PART_THREE</myTag> 
     <myTag> PART_FOUR </myTag> 
    </div> 
</body> 
</html> 

比方說,這是$內容。 現在,您可以看到我有4個自定義標籤(myTag),其中包含一個單詞內容。 (PART_ONE,PART_TWO等) 我想用4個不同的字符串替換那4個。這些後4個字符串數組中:

$replace = array("PartOne", "PartTwo", "PartThree", "PartFour"); 

我這樣做,但它並沒有成功地工作:

$content = preg_replace("/<myTag>(.*?)<\/myTag>/s", $replace, $content); 

所以,我想搜索myTags(發現4)並更換與陣列的一個條目。第一次出現應該由$ replace [0]替換,第二次出現由$ replace [1]替換,等等。 然後,它會以字符串的形式返回「新的」內容(不是數組),所以我可以使用它進一步解析。

我該如何認識到這一點?

+1

這將是非常非常簡單的搜索PART_ONE等... – Floris 2013-03-06 15:41:18

+2

http://stackoverflow.com/questions/1732348/regex-match-open-tags-except -xht ml-self-contained-tags – TFennis 2013-03-06 15:42:41

+0

哦,是的,我忘了告訴我不知道myTag的價值,所以PART_ONE可以同樣好「MY_ELEPHANT」。我應該可以在html模板中輸入任何內容,然後代碼將看到myTag標籤之間的任何內容。 此外,我不認爲這句話「你不能用正則表達式解析html」,因爲我不解析標籤的屬性,而只是一個標籤的值,這是一個簡單且安全的任務正則表達式。 – 2013-03-06 15:45:03

回答

-2

這應該是你要找的語法:

$patterns = array('/PART_ONE/', '/PART_TWO/', '/PART_THREE/', '/PART_FOUR/'); 
$replaces = array('part one', 'part two', 'part three', 'part four'); 

preg_replace($patterns, $replaces, $text); 

但要注意,這些順序運行,所以如果文本爲「PART_ONE`包含文本‘PART_TWO’隨後將被取代。

+1

源數據中標記的內容未知 – newman 2013-03-06 15:53:10

1

像下面這樣的東西應該工作:

$replace = array("PartOne", "PartTwo", "PartThree", "PartFour"); 
if (preg_match_all("/(<myTag>)(.*?)(<\/myTag>)/s", $content, $matches)) { 
    for ($i = 0; $i < count($matches[0]); $i++) { 
     $content = str_replace($matches[0][$i], $matches[1][$i] . $replace[$i] . $matches[3][$i], $content); 
    } 
} 
0

一種方法是遍歷你要替換陣列中的每個元素;用myDoneTag替換myTag這個詞,或者爲你完成的每一個替換一下,這樣你就可以找到下一個。然後你就可以隨時放回myTag末,你有你的字符串:

for(ii=0; ii<4; ii++) { 
    $content = preg_replace("/<myTag>.*<\/myTag>/s", "<myDoneTag>".$replace[ii]."<\/myDoneTag>", $content, 1); 
} 
$content = preg_replace("/myDoneTag/s", "myTag", $content); 
+0

如果正則表達式匹配,它將首次替換所有內容,而不關心其他3次循環迭代。 – h2ooooooo 2013-03-06 15:57:40

+0

嗯,雖然我已經想到這樣的答案並接受它,但我不認爲這是明智的,因爲它基本上是一個循環內的循環(preg_replace循環),因此這滯後於性能。 我想如果沒有其他的高性能解決方案,我只需要使用(X)HTML解析或類似的東西。 – 2013-03-06 15:59:15

+0

@ h2ooooooo - 你是對的。添加了「限制」參數並將其設置爲1 - 「僅替換第一個實例」。 – Floris 2013-03-06 15:59:55

0

用正則表達式,你可以像這樣:

$replaces = array('foo','bar','foz','bax'); 
$callback = function($match) use ($replaces) { 
     static $counter = 0; 
     $return = $replaces[$counter % count($replaces)]; 
     $counter++; 
     return $return; 
}; 
var_dump(preg_replace_callback('/a/',$callback, 'a a a a a ')); 

但實際上,在HTML標籤爲搜索時或XML,你想有一個解析器:

$html = '<!DOCTYPE html> 
<html> 
<head> 
    <title>test file</title> 
</head> 
<body> 
    <div id="dynamicContent"> 
     <myTag>PART_ONE</myTag> 
     <myTag>PART_TWO </myTag> 
     <myTag> PART_THREE</myTag> 
     <myTag> PART_FOUR </myTag> 
    </div> 
</body> 
</html>'; 

$d = new DOMDocument(); 
$d->loadHTML($html); 
$counter = 0; 
foreach($d->getElementsByTagName('mytag') as $node){ 
     $node->nodeValue = $replaces[$counter++ % count($replaces)]; 
} 
echo $d->saveHTML();