Reputation: 188
I tried to use this to solve a problem: I would like to replace a text with a text link this way.
But if I use this source code:
$dom = new DOMDocument;
$dom->loadHTML($html_content);
function preg_replace_dom($regex, $replacement, DOMNode $dom, array $excludeParents = array()) {
if (!empty($dom->childNodes)) {
foreach ($dom->childNodes as $node) {
if ($node instanceof DOMText &&
!in_array($node->parentNode->nodeName, $excludeParents))
{
$node->nodeValue = preg_replace($regex, $replacement, $node->nodeValue);
}
else
{
preg_replace_dom($regex, $replacement, $node, $excludeParents);
}
}
}
}
preg_replace_dom('/match this text/i', "<a href='http://test.de'>test</a>", $dom->documentElement, array('a'));
The text gets replaced, but <a href='http://test.de>test</a>
is printed as plain text, not as link.
How can I solve this?
Upvotes: 1
Views: 961
Reputation: 3280
This isnt as clean as I would have liked it to be but I got it working. I know this is an old question now but the answer is still relevant. You will need to pass the dom document into the method as you have to create a new HTML node to replace the old one. You cant just replace the text with HTML you have to replace the HTML node with a new HTML node. Would love to hear any suggestions on how this could be improved upon
private function _preg_replace_dom($regex, $domDocument, $replacement, DOMNode $dom, array $excludeParents = array()) {
if (!empty($dom->childNodes)) {
$replacementNodes = array();
foreach ($dom->childNodes as $node) {
if ($node instanceof DOMText && !in_array($node->parentNode->nodeName, $excludeParents))
{
//$node->nodeValue = preg_replace($regex, $replacement, $node->nodeValue);
$replacementHtml = preg_replace($regex, $replacement, $node->nodeValue);
$linkReplacement = $domDocument->createDocumentFragment();
$linkReplacement->appendXML($replacementHtml);
$tmpreplacement = new stdClass();
$tmpreplacement->oldNode = $node;
$tmpreplacement->newNode = $linkReplacement;
$replacementNodes[] = $tmpreplacement;
}
else
{
$this->_preg_replace_dom($regex, $domDocument, $replacement, $node, $excludeParents);
}
}
foreach($replacementNodes as $replacement)
{
$dom->replaceChild($replacement->newNode, $replacement->oldNode);
}
}
}
Upvotes: 0
Reputation: 1508
As I can see a '
is misplaced,
<a href='http://test.de>test</a>'
This is not something you should want, replace it with this,
<a href='http://test.de'>test</a>
As I've seen this Link, you may use preg_replace()
instead of preg_replace_dom()
at your last line of code.
Hope this helps.
Upvotes: 1