I have a text. In this text is a picture. I would like to replace every word Berlin with a link. Now I have the problem, which stands in the old part of the picture also Berlin and this is also replaced.
<?php
$content = "
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
<img class='bild' src='https://berlin.link/ alt='Bild von Berlin' width='300' height='200' />
Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet, vulputate, arcu.
";
$content = str_replace("Berlin", "<a href='//Berlin.test'>Berlin</a>", $content);
return $content;
?>
Is there a possibility that the Berlin in the picture is not replaced? Note The code is just an example. I usually get content from wordpress. But that should have nothing to do with it. I think.
Try this:
$content = "Berlin Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. <img class='bild' src='https://berlin.link/ alt='Bild von Berlin' width='300' height='200' /> Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede.";
$replaced = preg_replace('/<.*?>(*SKIP)(*FAIL)|Berlin/', "<a href='//Berlin.test'>Berlin</a>", $content);
var_dump(htmlentities($replaced));
So using preg_replace, the first part of the regex (before the | symbol) tells it to skip anything inside a <...> tag. After the | is what you want to replace. The second parameter is what you want it to be replaced with.
Hope this helps!
Credit goes to: https://stackoverflow.com/a/29973967/3884381 (I had done this kind of thing before but couldn't remember the specifics so had to look it up.)
As usual, the most reliable way to parse HTML is with a DOM parser, not string manipulation. This is fairly complicated but will not fail when presented with odd situations.
$content = "
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
<img class='bild' src='https://berlin.link/' alt='Bild von Berlin' width='300' height='200' />
Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet, vulputate, arcu.
Berlin
";
$search = "Berlin";
$replace_href = "//Berlin.test/";
$dom = new DomDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DomXPath($dom);
// here we search for every text node with the search term in it
$nodes = $xpath->query("//text()[contains(., \"$search\")]");
foreach ($nodes as $node) {
// explode the string at the search term to get an array
$parts = explode($search, $node->nodeValue);
// treat the first one differently because it comes before any matches
$part1 = $dom->createTextNode(array_shift($parts));
$node->parentNode->insertBefore($part1, $node);
// now go through the rest of the string parts
foreach ($parts as $part) {
// create the a element, set the attribute value and text content
$anchor = $dom->createElement("a");
$anchor->setAttribute("href", $replace_href);
$anchor->appendChild($dom->createTextNode($search));
// append it in place
$node->parentNode->insertBefore($anchor, $node);
// and then put the original text back
$node->parentNode->insertBefore($dom->createTextNode($part), $node);
}
// get rid of the original text node
$node->parentNode->removeChild($node);
}
echo $dom->saveHTML();
Output:
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
<img class="bild" src="https://berlin.link/" alt="Bild von Berlin" width="300" height="200">
Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet, vulputate, arcu.
<a href="//Berlin.test/">Berlin</a>
</p>