Naja ganz so einfach ist das nicht. Wenn beim Wort Text im Link
noch ein Leerzeichen folgt, geht diese Variante nicht mehr. Oder es folgt noch ein Wort im Link, dann geht die Variante auch nicht mehr. Es ist einfach zu Unsicher, um wirklich ausserhalb von Links sauber zu ersetzen.
Mein Hintergedanke geht einen völligen anderen Weg, und beruht auf die Aussage:
Ja, leider erstelle ich nicht den Content und deswegen kann ich mich auf sollte nicht verlassen
Nunja, ich habe mal versucht, das ganze etwas anders zu lösen. Mein Gedanke war, man müsste erstmal alle Links raus nehmen, das gesuchte Wort dann suchen und ersetzen, und dann wieder alle vorher entfernten Links im String wieder einfügen.
Das hätte den Vorteil, dass 100%ig nie in einen Link ersetzt wird, da diese vorher schon aus dem String genommen wurden. Natürlich hat das ganze auch Nachteile. Die folgene Funktion ist nicht für Ausgaben gedacht, eher sollte man diese Funktion nur bei Eingaben machen.
Und so sieht meine Lösung aus:
Code: Alles auswählen
$string = '
Das ist eine Test-Zeile mit <a href="#">Test</a>, einen Test mit Test im
Link <a href="#">Test</a> mit Wort Test und <a href="#">Test</a>.
';
function set_replace($suchwort, $string) {
preg_match_all('~<a.*?>.*?</a>~ism', $string, $array_links, PREG_OFFSET_CAPTURE);
$string_len = 0;
for ($i = 0; $i < count($array_links[0]); $i++ )
{
$array_suche[$i] = $array_links[0][$i][0];
$array_ersatz[$i] = '[link'.$i.']';
$string = substr_replace(
$string,
$array_ersatz[$i],
$array_links[0][$i][1] - $string_len, strlen($array_links[0][$i][0]) );
$string_len += strlen($array_links[0][$i][0]) - strlen($array_ersatz[$i]);
}
$string = preg_replace('~[^\[]'.$suchwort.'[^\d+\]]~', ' <a href="#">'.$suchwort.'</a> ', $string);
return str_replace($array_ersatz, $array_suche, $string);
}
echo set_replace('Test', $string);
Vielleicht noch eine kleine Erklärung dazu.
Zunächst werden alle Links mit preg_match_all() erfasst, und mittels PREG_OFFSET_CAPTURE die jeweilige Postion im String ermittelt.
Dies ist wichtig, falls Links doppelt sind bzw. die selben Namen oder Verweise haben.
Dann geht die Funktion den String durch und erstellt eine Art Hilfs-Array $array_suche und $array_ersatz. Anstelle der alten Links wird ein Marker mittels substr_replace() gesetzt. substr_replace() ersetzt an einer bestimmten Stelle und nicht irgendwo. Auch diese Funktion ist nötig um nicht selbe Links zu erfassen. Im Beispiel wird also aus den ersten Link ein [link0], aus den nächsten ein [link1] etc...
Jetzt kommt erst preg_replace() zum Einsatz, und sucht jetzt das gesuchte Wort, was nicht in einen Marker steht. Da die Marker von der Funktion selber erzeugt werden, können wir also bestimmen wie diese auszusehen hat. Und man kann besser darauf Einfluss nehmen, dass bestimmte Teile im String nicht ersetzt werden sollen - siehe Zitat.
Zum Schluss werden nun alle vorher entfernten Link wieder im String zurück ersetzt. Hier kommen die Hilfs-Arrays wieder zum Einsatz. Allerdings drehen wir die Array dazu um:
str_replace($array_ersatz, $array_suche, $string);
Natürlich ist dieser Weg etwas mehr als der Einzeiler mit preg_replace(), aber ich hab mal versucht das Problem von einen anderen Weg aus zu lösen.
... war jetzt so mein Gedanke ...
