preg_replace erweitern?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • preg_replace erweitern?

    Guten Abend

    Erstmal ein Hallo an Alle. Wie man schwer erkennen kann bin ich neu hier, und freue mich das ich dieses Board heute gefunden habe.

    Aber wie das leben schon spielt habe ich bereits ein Problem mit preg_replace.

    Ich bin mir grad ein kleines Ratespiel am erstellen, wofür ich preg_replace benötige.

    Folgenden Code habe ich bisher:
    PHP-Code:
    $quizfirst_result mysql_query("SELECT * FROM quiz_firstq ORDER BY firstq_title ASC");
    while(
    $quiz_row $db->fetch_array($quizfirst_result)) {
     
    $qclassthis->search[] = "/ $quiz_row[firstq_title]/i";
     
    $qclassthis->replace[] = " <u>$quiz_row[firstq_ersatz]</u>";
     
    $qclassthis->search[] = "/$quiz_row[firstq_title] /i";
     
    $qclassthis->replace[] = "<u>$quiz_row[firstq_ersatz]</u> ";
     
    $qclassthis->search[] = "/$quiz_row[firstq_title] /i";
     
    $qclassthis->replace[] = "<u>$quiz_row[firstq_ersatz]</u> ";
     
    $qclassthis->search[] = "/ $quiz_row[firstq_title] /i";
     
    $qclassthis->replace[] = " <u>$quiz_row[firstq_ersatz]</u> ";

    Nach der WHILE wird das ganze dann via preg_replace ersetzt. In der Datenbank ist einfach nur das Suchwort drin und was er ersetzen soll. Diese Funktion wird bei jedem Eintrag aufgerufen. Also macht er das bei 5 Einträgen 5 mal (ähnlich wie bei einem Gästebuch eigentlich). Soweit funktioniert dies eigentlich auch.

    Nun zu meinen Problemen:
    Sagen wir mal ich Suche nach test5 und nach test6:
    1. So wie ich es habe werden die ersetzt. Jedoch nicht alle und teils zuviel. Ich möchte z.b. das er aaatest5aaa, test5aaa, aaatest5 oder test5-test nicht ersetzt, oder www.test.test5 auch nicht etc. Das selbe Problem ist zur Zeit wenn ich auf einer Zeile nur noch test5 am schluss habe, wird dies auch nicht ersetzt. Nun hier die Frage, kann ich preg_replace irgendwie erweitern, dass er mir dies macht wie gewünscht?

    2. Gibt es eine möglichkeit "Sätze" zu beachten?
    Also sagen wir ich habe als suchwörter test5, test6 und test5 test6.
    nun soll er mir bei einem Satz wo "test5 test6" so vorkommt, dies auch mit dem aus test5 test6 ersetzt und nicht einzeln?

    Ich würde mich freuen wenn mir einer weiterhelfen kann.

    Gruss

    Katharina

  • #2
    also, wenn ich das richtig interpretiere, läuft bei den preg-patterns
    folgendes:

    PHP-Code:
    $quizfirst_result mysql_query("SELECT * FROM quiz_firstq ORDER BY firstq_title ASC");
    while(
    $quiz_row $db->fetch_array($quizfirst_result)) {
            
    //titel zum ersten (leerzeichen vorn)
         
    $qclassthis->search[] = "/ $quiz_row[firstq_title]/i";
         
    $qclassthis->replace[] = " <u>$quiz_row[firstq_ersatz]</u>";
          
    //titel zum zweiten (leerzeichen hinten)
         
    $qclassthis->search[] = "/$quiz_row[firstq_title] /i";
         
    $qclassthis->replace[] = "<u>$quiz_row[firstq_ersatz]</u> ";
         
    //titel zum dritten (leerzeichen hinten)
         
    $qclassthis->search[] = "/$quiz_row[firstq_title] /i";
         
    $qclassthis->replace[] = "<u>$quiz_row[firstq_ersatz]</u> ";
         
    //titel zum vierten (leerzeichen vorn und hinten)
         
    $qclassthis->search[] = "/ $acronym_row[firstq_title] /i";
         
    $qclassthis->replace[] = " <u>$quiz_row[firstq_ersatz]</u> ";

    Also, dass "aaaatest5" ersetzt wird, is soweit klar, denn da ham wir ja den suchterm+leerzeichen am ende... bei test5-bla ham wir leerzeichen vorn und suchterm dahinter.

    probier mal, statt der " " ein "\s" zu verwenden.
    Dann mach dich mal zum thema Quantifier und Gruppen schlau...
    Dann wär noch die Idee, "\W" mal genauer unter die Lupe zu nehmen.

    Wenn du das alles zusammen hast, kannst aus den verschiedenen Patterns auch eine einzige machen.

    Momentan könntest auch noch mit str_replace() arbeiten, dass ist dann sogar schneller als preg_replace().

    GreeZ

    Kommentar


    • #3
      Hallo ankh

      Danke. Dieses Quantifier habe ich so gut wie ich konnte bereits mal vor dem Post hier durchgelesen. Leider habe ich nur ne englische konkrete Seite gefunden, die mich jedoch recht weitergebracht hat. Ich habe dies Problem mal vor 2 Wochen in angriff genommen, kam jedoch nie weiter. Irgendwie hat irgendwas nie gepasst. Meine obengenannte Lösung ist die einzige bez. die beste die ich bisher gefunden habe.
      Entweder hat er mir dann www.test.test5 nicht mehr geparst was richtig war, dafür andere dinge und vieles weiteres. Irgendwie kam bez. komme ich auf keinen Grünen Zweig.

      ggf hätte ich noch meinen zweiten Versuch posten sollen vielleicht hätte euch/mich dies weitergebracht. Hab den nun noch etwas erweitert mit dem tut das ich eben fand mit hilfe deiner begriffe.

      Ich habe den Pattern nun mal wie folgt geändert:
      /(?<!\w)(?<!\.)".$quiz_row['firstq_title']."(?!\.\w)(?!\-)(?!\w)/i
      So dies funktioniert relativ prächtig.
      Jedoch werden hier folgende dinge trotzdem ersetzt:
      aaa-test5 (test5-aaa jedoch nicht wie sich das gehört)
      aaatest5 (test5aaa jedoch auch nicht wie sich das gehört)
      Wenn ich am ende des Textes in einer alleinstehenden Zeile test5 schreibe wird dies nicht ersetzt.
      Alles andere klappt.

      Was hiermit nicht klappt, ist leider die Wortgruppen.
      Hast du ggf noch für die beiden Probleme eine lösung für mich?

      PS. sorry das $acronym_row was im code wist ist wohl falsch. das hab ich aus einem bestehenden php script mal genommen als ich bei den replace angefangen habe und es wohl nicht geändert.

      Gruss

      Katharina

      Kommentar


      • #4
        PHP-Code:
        //"quiz_row" ohne \\w und ohne\\. davor dem kein \\.\\w folgt und kein \\- und kein \\w 
        /(?<!\w)(?<!\.)".$quiz_row['firstq_title']."(?!\.\w)(?!\-)(?!\w)/
        probier mal so, is allerdings net getestet

        PHP-Code:
        //quiz_row ohne NICHT-Whitespace davor dem kein NICHT Whitespace folgt
        "/(?<!\\S){$quiz_row['firstq_title']}(?!\\S)/i" 
        und:
        deutsche doku

        http://www.php.net/download-docs.php
        Zuletzt geändert von ankh; 22.05.2005, 19:37.

        Kommentar


        • #5
          Hallo nochmals

          Erstmal danke für deinen Tipp.
          Nun funktioniert es noch ein stück mehr, aber was anderes geht nicht.
          Nun wird folgendes nicht geparst:
          "dies ist nur mal
          ein
          test5

          test6

          text
          test5"
          hier wird nun nur das letze test5 geändert die restlichen nicht mehr. Also das letze am Text was vorher das Problem war ist dafür nun behoben.
          "aaa test5
          aaa test5"
          hier wird nur das zweite test5 geändert.
          Er scheint mitten drin dann nichts mehr zu ersetzen. Das ist wirklich seltsam. Hast du ggf noch nen Tipp warum bez wie ich dies ändern kann. Irgendwie werde ich das gefühl nicht los das es nicht geht, wobei laut aussagen von anderen usern wo ich dies schon sah funktioniert es (geben den pattern nicht raus leider das ich mri das ansehen könnte).

          PS noch ne Idee zu wortgruppen?

          EDIT:
          Ich habe den pattern nun selber noch etwas abgeändert:
          /(?<!\S){$quiz_row['firstq_title']}(?!\.\w)(?!\-)(?!\w)/i
          Nun scheint seltsamerweise alles so zu funktionieren wie es soll.
          Kannst du mir sagen ob dies so korrekt ist, oder ob hier noch ein fehler vorliegt bez. irgendwas ggf. nicht geparst wird was sollte?

          Kennst du eine lösung bez gibt es überhaupt eine möglichkeit das wegen den Wortgruppen zu machen?

          Gruss

          Katharina

          Kommentar


          • #6
            also, wenn des so funzt, dann wird's wohl auch korrekt sein.
            Dann brauchst auch keine Wortgruppen o.ä.

            gibt sicherlich 'ne bessere Lösung.. die gibt's ja immer... ausserdem bin ich auch kein (reg)experte... (für sowas eigentlich immer Perl Progger fragen, die kennen nix anderes als regex )

            Kommentar


            • #7
              die assertion \b gibt übrigens eine wortgrenze an ... vielleicht hilfts ja.
              Die Zeit hat ihre Kinder längst gefressen

              Kommentar


              • #8
                Hallo

                Aber denkst du dies ist eine lösung die ich gut lassen kann?

                Zu den wortgruppen: Gibt es da eine möglichkeit? Denn dies benötige ich und dies funktioniert nicht.
                Nochmals zur Kurzen erklärung:
                Ich habe folgende wörter und folgender ersatz:
                test5 (rote farbe)
                test6 (blaue farbe)
                test5 test6 (Grüne farbe)
                So ersetzt er mir nur test5 also rot test6 also blau aber wenn dies zusammenvorkommt leider nicht.

                Edit @derHund danke dir. Hab da mal in den manuals geschaut nur kann ich dies überhaupt irgendwie für mein Problem anwenden, oder ist dies damit gar nicht möglich? Habe so leider noch nichts gefunden wie ich dies verbinden sollte miteinander.

                Gruss

                Katharina

                Kommentar


                • #9
                  also, für den Fall würd ich dir mehr als eine pattern vorschlagen,
                  eine, die die einzelbegriffe sucht und färbt.
                  eine, die die kombinationen daraus sucht und färbt.

                  hab das mal exemplarisch mit deinem Teststring gemacht:

                  PHP-Code:
                   $pat1 "/(?<!\\S)(test5\\s+test6|test6\\s+test5)(?!\\S)/im";
                   
                  $pat2 "/(?<!\\S)(test5)(?!\\S)/im";
                   
                  $pat3 "/(?<!\\S)(test6)(?!\\S)/im";

                  $test "dies ist nur mal
                  ein
                  test5

                  test6

                  text
                  test5"
                  ;

                  $test preg_replace($pat3,"<font color=\"green\">$1</font>",$test);
                  $test preg_replace($pat,"<font color=\"red\">$1</font>",$test);
                  $test preg_replace($pat2,"<font color=\"blue\">$1</font>",$test);

                  echo 
                  $test
                  Bei mir funzt des so...
                  ach ja, bei dem ersten Vorschlag meinerseits hat's net funktioniert, weil in der mitte zwar ein whitespace char vor und nach z.B. test6 steht, aber der modifier "m" nicht gesetzt war ("m" = "multiline") daher hat die replace funktion die zeilenumbrüche nicht als whitespace beachtet.

                  edit: grml... immer doppelt escapen :/

                  Kommentar


                  • #10
                    Original geschrieben von ankh
                    also, für den Fall würd ich dir mehr als eine pattern vorschlagen,
                    eine, die die einzelbegriffe sucht und färbt.
                    eine, die die kombinationen daraus sucht und färbt.

                    hab das mal exemplarisch mit deinem Teststring gemacht:

                    PHP-Code:
                     $pat1 "/(?<!\\S)(test5\\s+test6|test6\\s+test5)(?!\\S)/im";
                     
                    $pat2 "/(?<!\\S)(test5)(?!\\S)/im";
                     
                    $pat3 "/(?<!\\S)(test6)(?!\\S)/im";

                    $test "dies ist nur mal
                    ein
                    test5

                    test6

                    text
                    test5"
                    ;

                    $test preg_replace($pat3,"<font color=\"green\">$1</font>",$test);
                    $test preg_replace($pat,"<font color=\"red\">$1</font>",$test);
                    $test preg_replace($pat2,"<font color=\"blue\">$1</font>",$test);

                    echo 
                    $test
                    Bei mir funzt des so...
                    ach ja, bei dem ersten Vorschlag meinerseits hat's net funktioniert, weil in der mitte zwar ein whitespace char vor und nach z.B. test6 steht, aber der modifier "m" nicht gesetzt war ("m" = "multiline") daher hat die replace funktion die zeilenumbrüche nicht als whitespace beachtet.

                    edit: grml... immer doppelt escapen :/
                    Hallo nochmals

                    Wie hätte denn dien pattern aussehen müssen das es deinermeinung nach auch geht? Verstand das nicht grad mit diesem m

                    Zu deinem Code: Nur leider kann ich den so nicht anwenden. Egal wie ich den drehe und wende.
                    Das ganze wird ja nur aus der Datenbank gelesen, so wie du es in meinem ersten Beitrag siehst. So kann ich dies ja so gar nicht anwenden. Hmm ist das alles kompliziert zum teil Vielleicht hast ja noch ne idee.

                    Gruss

                    Katharina

                    Kommentar


                    • #11
                      mkay... ich versuch's mal allgemeiner:

                      für die Wortkombinationen wünscht du ja eine andere Darstellung / Formatierung als für die Einzelworte, wenn ich das richtig verstanden habe.

                      Sowohl Suchwort alsauch Ersetzung sind in die DB geschrieben, richtig?

                      Erzeugst du die Wortkombinationen aus einzelworten, oder sind die separat hinterlegt?

                      wenn ja, dann kümmere dich zunächst um die kombinationen und ersetze diese mit ihrer Formatierung. Und zwar so, dass sie danach nicht mehr mit dem Suchmuster für die Einzelworte übereinstimmen.

                      zum "m":

                      in der pattern sieht's ja so aus "/suchmuster/modifier"
                      modifier können z.B. sein:
                      i (ignore case)
                      m (multiline)

                      wenn der modifier "m" nicht gesetzt ist, dann werden Zeilenumbrüche im zu durchsuchenden String entfernt/ignoriert.
                      ist "m" gesetzt, werden die Zeilenumbrüche mit in den Vergleich einbezogen.

                      für bessere Hilfe, müsste ich mehr code sehen... bzw mehr von dem, was nachher in die patterns geladen werden soll.

                      Kommentar


                      • #12
                        Guten Morgen

                        Danke für deinen Rat. Das hat soweit super geholfen.
                        Nur bei der Wortgruppe klappt eines noch nicht ganz.
                        Ich habe es nun mal andersrum ausgelesen (muss dann noch herausfinden wie ich die dinge aus der Datenbank nach der wortanzahl auslesen kann)

                        Wie im ersten beitrag wird dies in der WHILE gemacht wie du es dort siehst. Jedoch ist nun so, dass er es zweimal ändern. Alos zuerst das doppelwort aber das einzelwort im doppelwort ebenfalls nochmals.
                        Gibt es da abhilfe?

                        PS wie muss ich eigentlich umlaute aus der DB behandeln. wenn ich tesüt als wort habe (als beispiel) erkennt er dies wegem umlaut wohl nicht.

                        Gruss

                        Katharina

                        Kommentar


                        • #13
                          Morjen!

                          hmm... das klärt die Frage noch nicht, ob die Wortgruppen als selbständiger Eingrag in der DB stehen, oder ob sie aus beliebigen kombinationen der einzelwort Einträge erzeugt werden.

                          Ich vermute mal, die wortgruppen stehen als separater Eintrag in der DB. Dann würde ich vorschlagen, dass du die DBQuery so einstellst, dass du zunächst die wortgruppen bekommst, dann die Einzelworte.

                          Die Umlaute....
                          da würde ich dir vorschlagen, mit htmlentities() oder htmlspecialchars() zu arbeiten.

                          Solltest für die Anzeige sowieso, wegens der internationalisierung.

                          Aber jetzt fahr ich erstmal zur Arbeit, da hab ich mehr zeit für regex probleme

                          Kommentar


                          • #14
                            Guten Morgen

                            Das tut mir leid sorry. Bin doch ein kleines Doofchen. Ja diese sind direkt als Wortgruppe in der DB.
                            Leider passiert eben dann das das es wie zweimal ersetzt wird wie oben beschrieben:

                            Umlaute und sonderzecihen:
                            Hab ich mal biem preg_replace mit eingefügt beim suchstring. Leider ersetzt er es aus irgendeinem Grund immer noch nicht. Seltsam. Habe es mit beidem versucht. Die Werte werden mittels addslashes in die DB gespeichert.

                            Gruss

                            Katharina

                            Kommentar


                            • #15
                              Wenn du htmlentities() auf firstq_title und firstq_ersatz anwendest, dann müsste es auch mit Umlauten/Sonderzeichen gehen.

                              Wenn du jetzt die Wortgruppen zuerst suchst und ersetzt, z.B. in einer pattern, ddie ein Leerzeichen vor/hinter dem Suchmuster erwartet, und du die Wortgruppen so ersetzt, dass vor/hinter den Einzelbegriffen kein Leerzeichen mehr zu finden ist,

                              beispiel:

                              suchen: eine wortgruppe
                              ersetzen: <font color="red">eine wortgruppe</font>

                              suchen: eine
                              wird nicht gefunden, da statt dem " " jetzt ein ">" vor "eine" steht.


                              passen sie nicht mehr in die pattern, wenn die Einzelbegriffe gesucht und ersetzt werden sollen.
                              Damit kannst du sowohl Gruppen als auch einzelne Worte unterschiedlich einfärben.

                              Kommentar

                              Lädt...
                              X