Michael: REGEX - Allem außer mit " eingeschlossen, ein * werden

Hallo!

Für eine MYSQL-Volltextsuche möchte ich den Suchstring bearbeiten. Dazu sollenen allen Wörtern im String ein * angefügt werden, aber nicht Wörtern, die mit doppelten Anführungszeichen eingeschlossen sind.
Bsp: Ich will suchen -> Ich* will* suchen*
"Ich will" nach etwas suchen -> "Ich will" nach* etwas* suchen*

Nach stundenlangem Probieren habe ich folgendes Ergebnis:
eregi_replace('("{0}.{1,}"{0})', "\1*", $suchwort)
Nur leider sieht das Resultat dafür so aus: "Ich will" nach etwas suchen -> "Ich will" nach etwas suchen*. Nur das letzte Wort bekam ein * angehangen.

Da ich leider nicht ganz so viel Ahnung von den PHP Regex habe, würde ich mich freuen, wenn mir da jemand weiterhelfen könnte.

Grüße
Michael

  1. Ups, habe mich da leider bei der Überschrift vertippt, soll natürlich "REGEX - Allem außer mit " eingeschlossen, ein * anhängen" heißen, vielleicht kann das ein Mod ändern. Danke!

  2. Huhu Michael

    Bsp: Ich will suchen -> Ich* will* suchen*
    "Ich will" nach etwas suchen -> "Ich will" nach* etwas* suchen*

    Da ich leider nicht ganz so viel Ahnung von den PHP Regex habe, würde ich mich freuen, wenn mir da jemand weiterhelfen könnte.

    Das lässt sich u.U. ohne reguläre Ausdrücke einfacher lösen.

    Dazu brauchtst Du nur den String Zeichen für Zeichen durchgehen.

    Triffst Du dabei auf ein Anführungszeichen "merkst" Du Dir ob Du "drinnen" oder "draussen" bist.
    Dazu setzt Du eine Variable (flag) wechselweise auf true/false.

    Triffst Du hingegen auf ein Leerzeichen entscheidest Du je nach dem flag ob da noch ein Sternchen ergänzt werden soll.

    Die einzelnen Zeichen werden zu einem neuen String zusammengesetzt.

    So ungefähr jedenfalls.

    Viele Grüße

    lulu

    --
    bythewaythewebsuxgoofflineandenjoytheday
    1. Das lässt sich u.U. ohne reguläre Ausdrücke einfacher lösen.
      Dazu brauchtst Du nur den String Zeichen für Zeichen durchgehen.
      Triffst Du dabei auf ein Anführungszeichen "merkst" Du Dir ob Du "drinnen" oder "draussen" bist.
      Dazu setzt Du eine Variable (flag) wechselweise auf true/false.
      Triffst Du hingegen auf ein Leerzeichen entscheidest Du je nach dem flag ob da noch ein Sternchen ergänzt werden soll.
      Die einzelnen Zeichen werden zu einem neuen String zusammengesetzt.
      So ungefähr jedenfalls.

      Hallo lulu!

      Vielen Dank für diesen Denkanstoß - das war die Idee, die mir gefehlt hat! Habe es auch "so ungefähr" implementiert, falls es jemanden interessiert:
      $q = trim($q);
      $q = eregi_replace('[^a-z0-9äöüß +-]"', "", $q);
      // Zuviele Leerzeichen rausfiltern
      $q = ereg_replace("[[:space:]]{2,}", " ", $q);
      // Allen Wörtern außer in "" eingeschlossenen ein * anhängen
      $quote=false;
      for ($i=0; $i<strlen($q); $i++) {
       // Flag bei Anführungszeichen negieren
       if ($q{$i} == '"') {
        $quote=!$quote;
       // Wenn kein Anführungszeichen offen und dies kein Leerzeichen
       // und (danach der String zu Ende oder ein Leerzeichen folgt)
       } elseif (!$quote && !ereg('[+ -]', $q{$i}) && (!$q{$i+1} || $q{$i+1} == " ")) {
        $q = substr($q, 0, $i+1)."*".substr($q, $i+1, strlen($q)-1);
        // $i ums eins erhöhen, da ja ein Zeichen hinzugefügt wurde
        $i++;
       }
      }

      Grüße
      Michael

      1. Huhu Michael

        Habe es auch "so ungefähr" implementiert, falls es jemanden interessiert:

        Ja mich :-)

        $q = trim($q);
        $q = eregi_replace('[^a-z0-9äöüß +-]"', "", $q);
        // Zuviele Leerzeichen rausfiltern
        $q = ereg_replace("[[:space:]]{2,}", " ", $q);
        // Allen Wörtern außer in "" eingeschlossenen ein * anhängen
        $quote=false;
        for ($i=0; $i<strlen($q); $i++) {
        // Flag bei Anführungszeichen negieren
        if ($q{$i} == '"') {
          $quote=!$quote;
        // Wenn kein Anführungszeichen offen und dies kein Leerzeichen
        // und (danach der String zu Ende oder ein Leerzeichen folgt)
        } elseif (!$quote && !ereg('[+ -]', $q{$i}) && (!$q{$i+1} || $q{$i+1} == " ")) {
          $q = substr($q, 0, $i+1)."*".substr($q, $i+1, strlen($q)-1);
          // $i ums eins erhöhen, da ja ein Zeichen hinzugefügt wurde
          $i++;
        }
        }

        Fein. Interessant wie unterschiedlich man so eine Aufgabe lösen kann. Hier mal meine Variante, ist quasi das gleiche aber doch ein bischen anders.

        Falls es jemanden interessiert:

        <?php

        $s = '"ich     will"    nach     "etwas suchen" was ich verloren habe';

        // überzähligen whitespace reduzieren
        $s = trim($s);
        $s = preg_replace('#\s+#', ' ', $s);

        // am Ende ein Leerzeichen ergänzen, ...
        // ... damit der letzte Begriff auch ein Sternchen bekommt

        $s .= ' ';

        $l = strlen($s);

        $in_quotes = false;
        $tmp = '';

        for ($i = 0; $i<$l; $i++){
           $char2use = $s[$i];

        if ($char2use == '"'){
               $in_quotes = !$in_quotes;
           }

        if ($char2use == ' ' && !$in_quotes && $lastchar !='"'){
               $char2add = '* ';
           }else{
               $char2add = $char2use;
           }

        $tmp .= $char2add;
           $lastchar = $char2use;
        }

        echo $tmp;
        ?>

        Viele Grüße

        lulu

        --
        bythewaythewebsuxgoofflineandenjoytheday