2013-03-06 46 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();