Как заменить текст в HTML

Из этого вопроса: Какой шаблон регулярного выражения мне нужен? Я использовал следующий код:

function process($node, $replaceRules) { if($node->hasChildNodes()) { foreach ($node->childNodes as $childNode) { if ($childNode instanceof DOMText) { $text = preg_replace( array_keys($replaceRules), array_values($replaceRules), $childNode->wholeText ); $node->replaceChild(new DOMText($text),$childNode); } else { process($childNode, $replaceRules); } } } } $replaceRules = array( '/\b(c|C)olor\b/' => '$1olour', '/\b(kilom|Kilom|M|m)eter/' => '$1etre', ); $htmlString = "<p><span style='color:red'>The color of the sky is: gray</p>"; $doc = new DOMDocument(); $doc->loadHtml($htmlString); process($doc, $replaceRules); $string = $doc->saveHTML(); echo mb_substr($string,119,-15); 

Он работает нормально, но он терпит неудачу (поскольку дочерний узел заменен на первый экземпляр), если html имеет текст и HTML. Поэтому он работает

 <div>The distance is four kilometers</div> 

но нет

 <div>The distance is four kilometers<br>1000 meters to a kilometer</div> 

или

 <div>The distance is four kilometers<div class="guide">1000 meters to a kilometer</div></div> 

Любые идеи метода, который будет работать на таких примерах?

Вызов $node->replaceChild приведет к $node->childNodes итератора $node->childNodes . Сначала вы можете получить дочерние узлы, а затем обработать их:

 function process($node, $replaceRules) { if($node->hasChildNodes()) { $nodes = array(); foreach ($node->childNodes as $childNode) { $nodes[] = $childNode; } foreach ($nodes as $childNode) { if ($childNode instanceof DOMText) { $text = preg_replace( array_keys($replaceRules), array_values($replaceRules), $childNode->wholeText); $node->replaceChild(new DOMText($text),$childNode); } else { process($childNode, $replaceRules); } } } }