Hilfe - Suche - Mitglieder - Kalender
Vollansicht: preg_replace Funktion gesucht zum ersetzen einzelner Wörter in HTML
Forum Sefrengo.org > Allgemeine Foren > Offtopic
bjoern
Ich breche mir gerade einen ab bei der Programmierung eines reguären Ausdrucks. Vielleicht weiß ja einer von euch Rat.

Ich habe folgenden Text:

ZITAT
Lorem ipsum <a href="http://www.xy.de">sit dolor</a> amet, consectetuer adipiscing elit. Vivamus eget nisi. Donec suscipit. Aenean hendrerit augue! Nam justo urna, dictum eu, porttitor eu; accumsan id, eros. Maecenas in justo pharetra <a href="sit">dolor</a> sapien facilisis <span class="dolor">vestibulum</span>. Curabitur facilisis sem ac mauris. Cras massa. Praesent in mauris. Aliquam porta sapien nec velit vehicula accumsan. Fusce a lectus?


In diesem Text möchte ich nun alle Vorkommen des Wortes "dolor" durch "<a href="http://www.google.de">dolor</a>" ersetzen. Bedingungen:
* Innerhalb von Tags wird das Wort nicht ersetzt
* Ist das Wort schon verlinkt (auch als Teilwort) findet dort auch keine Ersetzung statt

Ich hab mit einigen regulären Ausdrücken umgespielt und frage mich nun, ob das Problem mit einem regulären Ausdruck überhaupt lösbar ist.
Daniel
Mit einem normalen reguläre Ausdruck geht das leider nicht (da ja -- wenn man mal Erweiterungen wie Assertions absieht, die hier ja leider auch nicht helfen -- reguläre Ausdrücke nur kontextfreie Grammatiken abbilden können)

Aber das hier macht, was du willst und ist beinahe pures RegEx smile.gif

QUELLTEXT
<?php

$text = <<<ENDE
Lorem ipsum <a href="http://www.xy.de">sit dolor</a> amet, consectetuer adipiscing elit. Vivamus eget nisi. Donec suscipit. Aenean hendrerit augue! Nam justo urna, dictum eu, porttitor eu; accumsan id, eros. dolor Maecenas in justo pharetra <a href="sit">dolor</a> sapien facilisis <span class="dolor">vestibulum</span>. Curabitur facilisis sem ac mauris. Cras massa. Praesent in mauris. Aliquam porta sapien nec velit vehicula accumsan. Fusce a lectus?
ENDE;

$word = "dolor";
$word_e = preg_quote($word,'~');

$processed = preg_replace_callback("~(<a[^>]*href.*{$word_e}.*</a>)|(<[^>]+{$word_e}[^>]*>)|($word_e)~Uims", 'linkify', $text);

echo $processed;

function linkify($match){
    //print_r($match);
    if (isset($match[3])) {
        return "<a href=\"http://www.google.de/\">".htmlentities($match[3])."</a>";
    } else {
        return $match[0];
    }
}


Die Idee dahinter: alles, was Du nicht ersetzt haben möchtest, musst Du explizit "wegmatchen".
mvsxyz
Cool. cool.gif
saschapi
ZITAT(mvsxyz @ Tue. 28. October 2008, 09:32) *
Cool. cool.gif

Zustimmung! cool.gif
bjoern
Das kommt sofort in meine PHP Trickkiste. Ein super Ansatz. Ich hab mir schon Gedanken darüber gemacht, den Zieltext in eigene Tokens zu zerlegen, damit ich das vernünftig ersetzt bekomme. DANKE!
bkm
ZITAT(bjoern @ Tue. 28. October 2008, 15:09) *
Das kommt sofort in meine PHP Trickkiste. Ein super Ansatz. Ich hab mir schon Gedanken darüber gemacht, den Zieltext in eigene Tokens zu zerlegen, damit ich das vernünftig ersetzt bekomme. DANKE!

@bjoern
hast du das mittlerweile schon mal im einsatz erprobt ?
kann es sein um beim beispiel von oben zu bleiben, das auch (kann sein das wort gibt es nicht wink.gif ) dolore somit gefunden und ersetzt wird ???
Daniel
ZITAT(bkm @ Fri. 28. November 2008, 12:53) *
@bjoern
hast du das mittlerweile schon mal im einsatz erprobt ?
kann es sein um beim beispiel von oben zu bleiben, das auch (kann sein das wort gibt es nicht wink.gif ) dolore somit gefunden und ersetzt wird ???


Ja, das ist auch so gewollt im Beispiel. Wenn du den Suchbegriff nur als ganzes Wort finden moechtest, musst du per "assertion" sicherstellen, dass es sich bei der Fundstelle um ein alleinstehendes Wort handelt.

QUELLTEXT
       $processed =  preg_replace_callback("~(<a[^>]*href.*{$word_e}.*</a>)|(<[^>]+\b{$word_e}\b[^>]*>)|\b($word_e)\b~Uims",  'linkify', $text);


Mehr zum Thema Assertions findet sich in der PHP-Hilfe: http://de.php.net/manual/de/reference.pcre...tern.syntax.php


PS: In dem Beispiel sollte es auch ohne Assertion gehen -- einfach \b durch \W oder \s ersetzen. Dann kann es allerdings in Sonderfaellen vorkommen, dass du nicht alle Stellen ersetzt.
Ein Beispiel:
Nimm den Text
QUELLTEXT
      a b a b a b

und das Suchwort "a b"
heraus kommt
QUELLTEXT
    <a href="...">a b</a> a b <a href="...">a b</a>

-> das mittlere "a b" wird nicht ersetzt, da das Leerzeichen bei der ersten Ersetzung schon "angefasst" wurde und jedes Zeichen im Text immer nur ein mal von preg_replace angesehen wird. (darauf baut ja der Trick mit dem "wegmatchen" auf)
bkm
@daniel
danke das mit \b{$word_e}\b funktioniert schon in meinem fall und somit ersetzt dolor auch nicht dolore mehr rolleyes.gif
Dieses ist eine vereinfachte Darstellung unseres Foreninhaltes. Um die detaillierte Vollansicht mit Formatierung und Bildern zu betrachten, bitte hier klicken.
Invision Power Board © 2001-2024 Invision Power Services, Inc.