Christian: (RegExp) Alles finden wo NICHT "xyz" drin vorkommt

Hi,

kann mir einer beim zusammenbasteln eines regulären Ausdrucks helfen??

Ich habe einen langen String, in dem ich nach einem Suchmuster alle Matches raussuche. Dazu benutze ich die Funktion preg_match_all.

Nun sind einige Matches sehr ähnlich, und unterscheiden sich nur durch eine bestimmte Zeichenkette an einer bestimmten Stelle.

Wie kann ich nun alles das finden, was zwar dem Suchmuster entspricht, aber nicht die Zeichenkette besitzt??

Bsp:

ich suche alles nach "/Ich liebe [a-zA-Z ]*./" .
Das sollte alle Sätze finden, wo steht "Ich liebe Vorname Nachname." XYZ sei dann mal irgendeine Buchstabenfolge.

Dann gebe es aber auch Sätze die so sein können:
"Ich liebe nicht Vorname"

Oben genanntes Suchmuster könnte das ja nicht unterscheiden!

Wie mach ich es also das alles gefunden wird, was mit "Ich liebe" anfängt, dann nicht die Zeichenkette "nicht" enthält, und dann beliebige Buchstaben und Whitespaces hat.

Habe schon probiert mit ^ (negation)

Aber Konstrukte wie (^nicht) oder ^(nicht) oder [1] oder [^nicht] haben alle nichts gebracht!

Wer weiß Rat??

Habt ihr auch einen Link für Reg Exp??

Danke
Christian


  1. nicht ↩︎

  1. und mit
    if ( preg_match("/XYZ/", $String) )
      - enthält was
    else
     - enthält XYZ nicht

    mfg

  2. ich bin dabei, hab einen moment geduld ;)
    Gruß
    Hanno

    1. Hiho wie versprochen :)

      Also zu deinem Problem:

      ich suche alles nach "/Ich liebe [a-zA-Z ]*./" .
      Das sollte alle Sätze finden, wo steht "Ich liebe Vorname Nachname." XYZ sei dann mal irgendeine Buchstabenfolge.

      Dann gebe es aber auch Sätze die so sein können:
      "Ich liebe nicht Vorname"

      Oben genanntes Suchmuster könnte das ja nicht unterscheiden!

      Wie mach ich es also das alles gefunden wird, was mit "Ich liebe" anfängt, dann nicht die Zeichenkette "nicht" enthält, und dann beliebige Buchstaben und Whitespaces hat.

      Das ist relativ schwierig für den Computer zu verstehen, denn wie soll er denn wissen, wann dein Liebesschwur zuende ist ? Nach 10 Zeichen, nach 3 Wörtern oder wie lange geht das ? Hört es mit einem Punkt auf ? sonst würde er ja aus einem bekloppten text wie
      "ich liebe dich wegen deines tollen haares deiner tollen figur und deinem knackarsch" das ganze "dich wegen deines tollen haares deiner tollen figur und deinem knackarsch" raussuchen, was er ja sicherlich nicht soll. Vorallem, wenn du sagst, da können auch 2 Wörter stehen oder mehr, wird es schwer, es zu filtern. Ok, wir gehen aber nun mal davon aus, dass du einfach einen "." hinter dem namen machst und dich auf leichte Sätze beschränken ( "Ich liebe klaus.", "ich liebe den tollen hecht hier.") Was besseres fällt mir im Moment nicht ein.
      Ok, bevor ich aber die Lösiung schreib, nochwas zu deinen Lösungsansätzen:

      Habe schon probiert mit ^ (negation)

      Aber Konstrukte wie (^nicht) oder ^(nicht) oder [1] oder [^nicht] haben alle nichts gebracht!

      Also das ^innerhalb einer noirmalen klammer oder vor der eckigen ist schwachsinn. Das klappt nur innerhalb von eckigen Klammern, also innerhalb einer Zeichenmenge. Da kommen wir auch shcon zum nächsten punkt. [^nicht] ist auch falsch, da er so alle zeichen außer n,i,c,h und t findet.
      Ok, gehen wir mal schritt für schritt vor. Ein Regex für das einfache beispiel ohne die "nicht"-ausklammerung wäre:
      "/(?:ich liebe|du liebst|er liebt|sie liebt|wir lieben|ihr liebt|sie lieben)[\x20]{1,}(.*)./Ui"
      So findet er auch nicht das wort "liebe" sondern nur konjugierte verben. Wichtig ist hierbei der Modifierer U, sonst nimmt er den letzten Punkt. U heißt, er soll den ersten Fund nehmen.
      Hier ein kleiner Code für den Anfang:
      ----------------------------------------
      <?
         $txt = 'ich liebe dich. ich liebe klaus. ich liebe den tollen hecht hier.';
         preg_match_all("/(?:ich liebe|du liebst|er liebt|sie liebt|wir lieben|ihr liebt|sie lieben)[\x20]{1,}(.*)./Ui",$txt,$arr);
         foreach($arr as $t1 => $t2)
            foreach($t2 as $t3 => $t4)
               print "<br>" . $t1 . " , " . $t2 . " ;" . $t3 . ": " . $t4;

      ?>
      ------------------------------------------
      So, nun aber zum richtigen Problem:
      Das "nicht" grenzt du so aus:
      "/(?:ich liebe|du liebst|er liebt|sie liebt|wir lieben|ihr liebt|sie lieben)[\x20]{1,}(?!nicht)(.*)(?!nicht)./Ui",

      Dazu hier noch das Beispiel
      ------------------------------------------
      <?
         $txt = 'ich liebe nicht dich. ich liebe klaus nicht. sie lieben den tollen hecht hier.';
         preg_match_all("/(?:ich liebe|du liebst|er liebt|sie liebt|wir lieben|ihr liebt|sie lieben)[\x20]{1,}(?!nicht)(.*)(?!nicht)./Ui",$txt,$arr);
         foreach($arr as $t1 => $t2)
            foreach($t2 as $t3 => $t4)
               print "<br>" . $t1 . " , " . $t2 . " ;" . $t3 . ": " . $t4;

      ?>
      -------------------------------------------
      Ich hoffe du kannst damit was anfa´ngen :)
      Gruß
      Hanno


      1. nicht ↩︎

      1. Vielen Danke, werds mir mal genauer anschauen!
        Besonders interessant wie ich ganze Zeichenketten ausgrenze! Bisher hab ich immer nur gelesen wie man einzelne zeichen mit [^abc] ausperrt.

        Gruß
        Christian

  3. Hallo Christian

    ich suche alles nach "/Ich liebe [a-zA-Z ]*./" .
    Das sollte alle Sätze finden, wo steht "Ich liebe Vorname Nachname." XYZ sei dann mal irgendeine Buchstabenfolge.

    Dann gebe es aber auch Sätze die so sein können:
    "Ich liebe nicht Vorname"

    Oben genanntes Suchmuster könnte das ja nicht unterscheiden!

    Wie mach ich es also das alles gefunden wird, was mit "Ich liebe" anfängt, dann nicht die Zeichenkette "nicht" enthält, und dann beliebige Buchstaben und Whitespaces hat.

    <?php  error_reporting(E_ALL);

    $text = 'Ich liebe Vorname Nachname.
    Ich liebe meine Frau vorzugsweise. Ich liebe nicht ist doch egal. Ich liebe php ob man dass liebe nennen soll.';

    preg_match_all ('=Ich liebe (?!nicht)[A-Za-z ]*\.=', $text, $matches);

    print_r($matches);

    /* Ausgabe

    Array
    (
        [0] => Array
            (
                [0] => Ich liebe Vorname Nachname.
                [1] => Ich liebe meine Frau vorzugsweise.
                [2] => Ich liebe php ob man dass liebe nennen soll.
            )

    )

    */

    ?>

    Danke

    Bitte

    Christian

    ich auch ;-)

    Gruß
      Christian

    1. Hi,

      danke!!

      (?!nicht)

      das meinte der andere auch schon!!

      Kann man mir das erklären?? Besonders das Fragezeichen! Was bringt das?
      Das ! als verneinung kann ich ja noch verstehen!

      Christian

      1. (?!nicht)
        Kann man mir das erklären?? Besonders das Fragezeichen! Was bringt das?
        Das ! als verneinung kann ich ja noch verstehen!

        Schau doch in's Manual http://www.php.net/manual/en/pcre.pattern.syntax.php
        such nach Assertions (Behauptungen)

        Gruß
          Christian