2013-03-06 4 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 개의 다른 문자열로 바꾸고 싶습니다.

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

내가 이런 짓을하지만, 성공적으로 작동하지 않습니다 : 그 후자의 4 문자열 배열에있는

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

그래서, 나는 (그것이 4를 발견) myTags를 검색하고 교체 할 어레이의 한 항목으로 첫 번째 항목은 $ replace [0], 두 번째 항목은 $ replace [1] 등으로 대체해야합니다. 그런 다음 "새로운"내용을 문자열이 아닌 배열로 반환하므로 사용할 수 있습니다. 추가 파싱.

어떻게 알 수 있습니까?

+1

것은 그것은 PART_ONE 등 ... – Floris

+2

http://stackoverflow.com/questions/1732348/regex-match-open-tags-except를 검색 할 훨씬 간단 많은 것 : XML, 당신은 파서를 원하는 -xht ml-self-contained-tags – TFennis

+0

오, 그래, 나는 myTag의 가치를 모른다는 것을 잊어 버렸다. 그래서 PART_ONE은 "MY_ELEPHANT"가 될 수있다. html 템플릿에 무엇이든 입력 할 수 있어야하며 코드는 myTag 태그 사이에 무엇이 있는지 볼 것입니다. 또한 나는 태그의 속성을 파싱하지 않기 때문에 "정규식으로 html을 파싱 할 수 없다"는 말은하지 않는다고 생각합니다. 태그의 속성을 파싱하지 않기 때문에 간단하고 안전한 작업임이 분명합니다. 정규식. –

답변

-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_TWO ''PART_ONE` 텍스트를 포함 '에 대한 텍스트.

+1

소스 데이터의 태그 내용을 알 수 없음 – newman

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

한 가지 방법은 당신이 대체 할 배열의 각 요소를 반복 할 것; 단어 myTagmyDoneTag 또는 완료 한 단어로 바꿔서 다음 단어를 찾으십시오. 그럼 당신은 항상 마지막에 다시 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

+0

흠, 나는 이미 이런 식으로 대답을하고 그것을 받아 들일 것이라고 생각하지만 기본적으로 루프 내의 루프 (preg_replace loops)이기 때문에 이것을 사용하는 것이 현명하다고 생각하지 않습니다. 따라서 이것은 성능보다 뒤처집니다. 다른 고성능 솔루션이 없다면 (X) HTML 구문 분석 또는 그와 비슷한 것으로 갈 것입니다. –

+0

@ h2ooooooo - 당신 말이 맞아요. "제한"매개 변수를 추가하고 1로 설정 - "첫 번째 인스턴스 만 바꾸기". – Floris

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 태그를 검색 할 때 또는

$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();