heinetz: Komisches Verhalten bei regulärem Ausdruck

Hallo Forum,

um Text im Content einer XHTML-Seite farblich zu markieren,
versuche ich ihn durch:

preg_replace('/(>[^<>]*)('.$mark_strA[$z].')([^<>]*<)/i', '${1}<span class="s_result">${2}</span>${3}', $html_str);

... mit einem <span> zu taggen.

Das Resultat ist allerdings merkwürdig. Ein Auszug daraus:

<p>
Die unabhängige Verbraucherberatung Stiftung Warentest hat 9.000 Medikamente für 185 Anwendungsgebiete ge
<span class="s_result">test</span>
et. Es handelt sich um die am häufigsten gekauften rezeptfreien Mittel und die wichtigsten vom Arzt verschriebenen Präparate.
</p>

Gefunden wurde "gestetet". "Warentest" jedoch nicht.

Warum ?
Bzw. Wie sieht das Suchmuster aus, wenn man im HTML-Code nur
innerhalb des angezeigten Textes Ersetzungen vornehmen und
Tags sicher ausschliessen will?

Danke für Tipps und

beste gruesse,
heinetz

  1. Hi,

    preg_replace('/(>[^<>]*)('.$mark_strA[$z].')([^<>]*<)/i', '${1}<span class="s_result">${2}</span>${3}', $html_str);

    ... mit einem <span> zu taggen.

    Das Resultat ist allerdings merkwürdig. Ein Auszug daraus:

    <p>
    Die unabhängige Verbraucherberatung Stiftung Warentest hat 9.000 Medikamente für 185 Anwendungsgebiete ge
    <span class="s_result">test</span>
    et. Es handelt sich um die am häufigsten gekauften rezeptfreien Mittel und die wichtigsten vom Arzt verschriebenen Präparate.
    </p>

    Gefunden wurde "gestetet". "Warentest" jedoch nicht.

    Die Variable $mark_strA[$z] enthält also den Text 'test', ja?

    Warum ?

    Weil reguläre Ausdrücke gierig, englisch greedy, sind - sie versuchen per Default immer so viel zu erwischen, wie möglich.
    Das, was du in deinem Suchmuster vor (test) stehen hast, nämlich (>[^<>]*), trifft auf *alles* zu, was vor dem "getestet" steht - auch auf "Warentest".
    Und da der Ausdruck von dem, auf das (>[^<>]*) zutrifft, möglichst viel zu finden versucht, sieht er das "test" in "getestet" als Treffer für die zweite Klammerung in deinem Ausdruck an, und alles davor als Treffer für die erste.

    Du müsstest also bspw. den Modifier U setzen, um dem Ausdruck seine Gierigkeit abzugewöhnen.

    (Damit wird hier natürlich nur noch das "test" in "Warentest" ersetzt, und das zweite nicht mehr. Denn für das, was zwischen diesen beiden Auftreten von "test" in deinem Text liegt, trifft dann (>[^<>]*) nicht mehr zu.)

    Bzw. Wie sieht das Suchmuster aus, wenn man im HTML-Code nur
    innerhalb des angezeigten Textes Ersetzungen vornehmen und
    Tags sicher ausschliessen will?

    Dazu findest du sicher einige Lösungsvorschläge, wenn du erst mal danach suchst.

    MfG ChrisB

    --
    Light travels faster than sound - that's why most people appear bright until you hear them speak.
    1. Hi,

      Und da der Ausdruck von dem, auf das (>[^<>]*) zutrifft, möglichst viel zu finden versucht, sieht er das "test" in "getestet" als Treffer für die zweite Klammerung in deinem Ausdruck an, und alles davor als Treffer für die erste.

      Danke, das bringt Licht in's Dunkel ;)

      Ich versuche seit Ewigkeiten, immer wieder den Durchbruch zu erleben und Reguläre Ausdrücke echt zu begreifen. Deshalb versuche ich's immer wieder selbst.

      Dazu findest du sicher einige Lösungsvorschläge, wenn du erst mal danach suchst.

      Und das hab ich getan und etwas gefunden, was ich zwar nicht verstehe, aber was funktioniert ;)

      danke und gruss,
      heinetz

      1. Hi,

        Dazu findest du sicher einige Lösungsvorschläge, wenn du erst mal danach suchst.

        Und das hab ich getan und etwas gefunden, was ich zwar nicht verstehe, aber was funktioniert ;)

        Wenn du zeigst, was - dann findet sich sicher jemand, der's erklären kann.

        MfG ChrisB

        --
        Light travels faster than sound - that's why most people appear bright until you hear them speak.