Florian Krismer: Problem mit regulären Ausdrücken

Hi!

Also ich möchte ein Script (Gästebuchscript) erzeugen, welches einen text, der besonders gekennzeichnet ist Fett schreibt. Das klingt vielleicht etwas kompliziert daher ein Beispiel:

als übergabewert wurde "?test? ist fett geschrieben" festgelegt und jetzt soll das Script die ? entfernen und dafür <b> bzw. </b> einfügen ich habe es bereits wie folgt leider ohne Erfolg probiert: $string = eregi_replace("\?([a-zA-Z0-9])\?",<b>([a-zA-Z0-9])</b>",$string)

Vielleicht kann mir jemand von euch helfen, wäre für jede Hilfe und jeden Tipp dankbar

Grüße Flo

  1. Überprüf mal die Mikroschalter Deiner Maus...

    Der (soeben erfundene) Titel: "Zittrigste Finger des Monats" geht an Dich :-)

    Bio

    1. Hmmm?

      Kess? Stefan?

      Erst heisst es, weniger NA und NI sollen gemacht werden, und dann verschwinden plötzlich ganze Threads!
      Und arme Leute wie ich stehen als total gestörte Idioten da, deren Postings überhaupt keinen Sinn machen!
      Findet Ihr das etwa gut? Lustig? Oder sowas? Naaa?

      Ich verlange Satisfaktion! Eine Entschuldigung! Ehrenrettung! Eine Erklärung!

      Sonst muß ich leider ein total okkultes Ritual zelebrieren und Euch mitsamt den 7 Postings irgendwo dort hinschicken, wo angeblich auch VOID und /dev/null zuhause sind... :-)

      Empörtst,

      :-(((

      Bio

  2. Hallo!

    als übergabewert wurde "?test? ist fett geschrieben" festgelegt und jetzt soll das Script die ? entfernen und dafür <b> bzw. </b> einfügen ich habe es bereits wie folgt leider ohne Erfolg probiert: $string = eregi_replace("\?([a-zA-Z0-9])\?",<b>([a-zA-Z0-9])</b>",$string)

    Also ich denke, meine Lösung ist auch nicht die wahre Lösung, aber es funktioniert! :-) Anstatt des Fragezeichens habe ich eine Raute genommen.

    Im ersten Durchlauf werden alle # durch ein <b> erstetzt. Im zweiten Durchlauf werden alle <b>, mit einem nachfolgendem Leerzeichen, den logischerweise folgt nach einem Wort ein Leerzeichen,  durch ein </b> mit einem Leerzeichen ersetzt.

    1. Ich habe nicht rausgefunden, wie man mit regulären Ausdrücken ein Leerzeichen abfragen kann!
    2. Ich habe auch nicht gefunden, wie man ein Leerzecihen erzwingen kann, also wie z.B. mit \n einen Zeilenumbruch.

    Wenn Du weist, mich interessiert es!

    $string = "#Hallo# wie #gehts# Dir? Mir gehts #ganz# gut!";

    // 1. Durchlauf
    $fastfertig = ereg_replace("#", "<b>", $string);

    //2. Durchlauf, nach <b> und </b> immer ein Leerzeichen
    $fertig = ereg_replace("<b> ", "</b> ", $fastfertig);

    echo ($fertig);

    mfg, André

    1. Hi Andre!

      Dabei kann ich dir wieder helfen: in html macht man es mit &nbsp ; (natürlich ohne abstand sonst wird es aber nicht angezeigt) die übergabe bei php3 & get-method erfolgt via + Zeichen. Mehr weiß ich auch nicht *gg*

      Grüße Flo

  3. als übergabewert wurde "?test? ist fett geschrieben" festgelegt und jetzt soll das Script die ? entfernen und dafür <b> bzw. </b> einfügen ich habe es bereits wie folgt leider ohne Erfolg probiert:
    $string = eregi_replace("\?([a-zA-Z0-9])\?",<b>([a-zA-Z0-9])</b>",$string)
    Vielleicht kann mir jemand von euch helfen, wäre für jede Hilfe und jeden Tipp dankbar

    Ich kann zwar kein PHP3, aber Dein Ausdruck sieht so aus, wie er auch in Perl aussehen würde.
    Als einzusetzende Zeichenkette willst Du aber im mittleren Teil nicht irgendwelche Buchstaben oder Ziffern haben, sondern diejenigen, die Du aus der analysierten Zeichenkette herausgefiltert hast. Dieses Teil-Ergebnis mußt Du also im zweiten Parameter der Funktion referenzieren. Bei Perl ginge das mit "\1" - wie es sich in PHP3 schreibt, kann ich Dir nicht sagen.

    Das fehlende Gänsefüßchen am Anfang des 2. Parameters hast Du gesehen?

  4. Hi!

    Probier mal folgendes:

    eregi_replace("\?([a-zA-Z0-9]+)\?","<b>\1</b>",$string);

    das + benötigst du, da sonst exakt ein Zeichen zwischen den ? sein müßte, damit ein Treffer erziehlt wird.
    Mit \1 referenzierst du den Treffer (und fügst ihn ein).

    mfG
    BRAND

    1. Hi!

      Also zuerst einmal DANKE, das war genau das, was ich gesucht habe. Nur habe ich etwas übersehen die Sonderzeichen ...
      Ich habe es mit eregi_replace("\?([a-zA-Z0-9-]$+)\?","<b>\1</b>",$string); versucht, da es für mich das logische war, doch leider hat es nicht funktioniert :(

      Grüße
      Flo

      1. Hi!

        Ich nehme an, da? das $ nur ein Tippfehler war.

        Wenn du alle Sonderzeichen (mit Ausnahme des "?" natürlich) berücksichtigen willst. Dann probier mal folgendes:

        eregi_replace("\?([^? ]+)\?","<b>\1</b>",$string);

        Das Führt zu treffern wo eine Zeichenkette zwischen zwei "?" steht, die aus MINDESTENS einem Zeichen besteht (+) und die KEIN "?" und KEIN " " enthält. (hinter dem Fragezeichen in der Liste ist ein Space, da sonst jedes "?" als FETT-Schrift-Anzeige gesehen wird - also auch Fragezeichen am Ende einer Frage).

        Es werden nun also auch alle Sonderzeichen berücksichtigt.

        Du kanns damit also nur einzelne Wörter FETT schreiben. Sinnvoller wäre ein Zeichen zur Kennzeichnung der FETT-Schrift zu verweden, das in normalen Text nur selten vorkommt (z.Bsp. # oder $)

        1. Hi!

          hm - jetzt funktionierts nur habe ich noch eine Frage: ist es möglich, das nach 2 sonderzeichen gesucht werden kann und dann vor allem (!) diese ausgeschlossen werden können?

          Grüße Flo

          1. Hi!

            versteh' ich jetzt nicht ganz.

            was meinst du mit "nach 2 sonderzeichen" suchen?

            Bezieht sich das auf das vorherige Problem? Also etwa statt dem "?" z. Bsp ein "%&" oder so? ... dann brauchst du die ja nur so in die Maske schreiben.

            also:

            eregi_replace("%&([^? ]+)%&","<b>\1</b>",$string);
            (die beiden Backslash wie beim "?" sind in diesem Fall nicht notwendig, weil "%" und "&" im Gegensatz zum "?" keine besondere Bedeutung in der Maske haben)

            Was meinst du mit "diese ausgeschlossen werden können"?
            Du kannst ja eben mit \1 das Teilergebnis in den () ansprechen.
            Wenn du sie nach dem replace noch im string haben willst, so schreib sie einfach wieder rein.
            (also den replace-string: "<b>%&\1%&</b>" oder "<b>\0</b>")

            war das jetzt verständlich?
            sonst beschreibe genauer, was du machen willst.

            mfG
            BRAND

            1. Hi!

              Ja dieser Teil, den du geschrieben hast war mir klar nur das Sperren der beiden Zeichen stellt für mich das Problem da also [^] mit zwei Zeichen, die nur in der Kombination nicht vorkommen dürfen, jedoch einzeln schon

              Also zb: string = "/% bla%bla/bla %/" - dieser String ist korrekt aber string = "/% blabla /%" -  ist falsch

              Grüße FK

              1. Hi!

                so, jetzt hast du mich erwischt;-)
                Wie man ein NICHT auf mehr als ein Zeichen gleichzeitig anwendet weiß ich auch nicht.

                Aber wenn du schon für das "<b>" ein "/%" und für das "</b>" ein "%/" verwendest, warum ersetzt du dann nicht einfach das "/%" durch ein "<b>" und das "%/" durch ein "</b>"

                eregi_replace("/%","<b>"); und
                eregi_replace("%/","</b>");

                mfG
                BRAND

                1. Hi!

                  Heute in der Nacht (so um ca. 2 Uhr) habe ich eine Lösung gefunden - nur ein Problem habe ich immer noch *grml*

                  Die Lösung: eregi_replace("/@ ([^<]+) @/","<b>\1</b>",$string);

                  Ich habe viel zu kompliziert gedacht ... es ist ja im Grunde egal, was in der Mitte steht - wichtig ist nur, dass das ganze mit /@ beginnt und mit @/ endet - es kann in der mitte auch /@ stehen egal nur mein Problem ist noch, wie kann ich alle Zeichen verwenden ohne irgendetwas auszuschließen? Muss ich da wieder zurück zu [a-zA-Z0-9] oder gibt es da was leichteres?

                  Grüße Flo

                  1. Hi!

                    Heute in der Nacht (so um ca. 2 Uhr) habe ich eine Lösung gefunden - nur ein Problem habe ich immer noch *grml*

                    Die Lösung: eregi_replace("/@ ([^<]+) @/","<b>\1</b>",$string);

                    Ich fürchte, daß das nicht die Lösung ist (außer du hast im string nur maximal einen Bereich der fett dargestellt werden soll.

                    Ich weiß nicht, ob dir ganz klar ist, welche Treffer diese Abfrage findet?

                    Du suchst also nach Zeichenketten, die mit "/@ " beginnen und mit " @/" enden,
                    dazwischen darf alles vorkommen außer einem "<".

                    Hast du nun in dem String den du durchsuchst mehrere "/@" und "@/" so ist die Maske nicht eindeutig, in diesem Fall wird als Ergebnis die längste gefundene Zeichenkette, die dieser Maske entspricht, ausgegeben.

                    Bsp:

                    "Das ist ein /@ Test @/!!!" wird zu "Das ist ein <b>Test</b>!!!" (das paßt ja
                    soweit)

                    ABER:

                    "/@ Das @/ ist ein /@ zweiter Test @/!!!" wird zu "<b>Das @/ ist ein /@ zweiter Test</b>!!!" ...hier gibt es nämlich zwei Lösungen, die der Maske entsprechen - einmal zwei kurze "Das" und "zweiter Test" und einmal eine lange "Das @/ ist ein /@ zweiter Test" -> und genau diese wird als Ergebnis ausgegeben werden.

                    Weiters würde ein "/@ Maus < Elefant @/" keinen Treffer erzielen, da du in der
                    Liste [^<] ja das "<" ausschließt.

                    »»wie kann ich alle Zeichen verwenden ohne irgendetwas auszuschließen?

                    Damit kein Zeichen ausgeklammert wird kannst du "(.+)" statt dem "([^<]+)" verwenden.

                    der Punkt "." ist quasi ein Platzhalter für irgendein Zeichen und das Plus "+" dahinter bedeutet, daß mindestens ein Zeichen an dieser Stelle vorkommen muß (es können aber auch mehr sein).

                    noc viel Spaß beim tüfteln ;-)

                    BRAND

                    1. Du hast schon recht, dass das mit dem dazwischen ist mir schon klar und das man nur einmal das <b> einsetzen kann - aber es ist auch sinnlos wenn 2 oder mehrere <b></b> ineinander geschachtelt sind, da es wirkungslos ist. Und das mit dem [^<] war nur eine Zwischenlösung und zuvor hatte ich eregi_replace("<","<",$string) gestellt gehabt, also hat sich das problem dort auch gelost - es war meine absicht keine html-codes zu integrieren, da es ein hohes sicherheitsrisiko darstellt, nicht die befehle aber die falschen syntaxe zb eine offenes fett (<b> ohne </b>) schreiben - netscape zeigt dann die Seite überhaupt nicht mehr an.

                      DANKE, für deine großartige Hilfe

                      Grüße
                      Florian