Marko Schilde: Regular Expressions

Hi,

Ich möchte einen String dahingehend checken, ob er bestimmte Zeichen in einer festen Reihenfolge enthält - also z.B. $string = "string"; muss die Zeichen t, r und n enthalten, und zwar genau in dieser Reihenfolge, egal was zwischen den Zeichen ist [dient dazu, die naughty language-Sperre in meinem Forum sicherer zu machen, so dass auch Stringderivate wie "Ar's**" (wir alle wissen, wofür die **'s stehen ;-) statt "Ars**" erkannt werden.

-M

  1. Auch hi!

    $string = "string";
    $found = ($string =~ /t.*?r.*n/) ? 1 : 0;

    Ob es allerdings gut ist, Deinem Forum solche Restriktionen aufzuerlegen, oder ob Du nicht besser auf den gesunden Menschenverstand Deiner Besucher vertrauen solltest, ... tja das steht auf einem anderen Blatt.

    Calocybe

    1. :-) Danke für die Antwort, aber wie würde der Code allgemein aussehen, d.h. für beliebige Zeichen?

      -M

      PS: Tja, die Erfahrung hat gezeigt, dass zu viel Toleranz zu nichts führt. Es braucht nur einen Störenfried und eine Handvoll Leute, die auf dessen Beleidigungen empfindlich reagieren, und schon wird aus einem beliebtem, gut besuchtem Forum eine niveaulose Kloake :-((( Da is nix mit Appellieren...

      1. :-) Danke für die Antwort, aber wie würde der Code allgemein aussehen, d.h. für beliebige Zeichen?

        Was meinst Du mit allgemein? Du musst eben die Buchstaben in der Reihenfolge hinschreiben, die Du brauchst und dann immer .*? dazwischen einfuegen. (Einfach .* geht auch, aber ich bilde mir ein, dass mit dem ? die Geschwindigkeit erhoeht wird, weil der Ausdruck dann nicht 'greedy' ist.)

        PS: Tja, die Erfahrung hat gezeigt, dass zu viel Toleranz zu nichts führt. Es braucht nur einen Störenfried und eine Handvoll Leute, die auf dessen Beleidigungen empfindlich reagieren, und schon wird aus einem beliebtem, gut besuchtem Forum eine niveaulose Kloake :-((( Da is nix mit Appellieren...

        Mmh, ich bilde mir ein, das dieses Forum noch nicht zur niveaulosen Kloake verkommen ist, obwohl wir auch manchmal ein paar Reibereien haben. Kannst ja Stefan mal fragen, wie er das gemacht hat. ;-)

        Calocybe

        1. Mmh, ich bilde mir ein, das dieses Forum noch nicht zur niveaulosen Kloake verkommen ist, obwohl wir auch manchmal ein paar Reibereien haben. Kannst ja Stefan mal fragen, wie er das gemacht hat. ;-)

          Calocybe

          Thnx alot für deine hilfreiche Antwort - und ich hab mich immer gewundert, weshalb /r.n/ z.B. nix gebracht hat.

          Hmmm ... und zur Forumproblematik ... nun, es ist ein himmelweiter Unterschied, ob sich zwei Forumbesucher einfach nur streiten [das gehört nun mal dazu], oder ob ein kranker Irrer versucht, das Forum mit wirklich miesen Beleidigungen [konstant unter der Gürtellinie] zuzuspammen und kaputtzumachen :-(

          Btw, es kann doch nicht schaden, Wörter wie "Wich**r" oder "Arsc*l**h" oder "du blöde S**" zu sperren; normale User verwenden sie eh nicht, und wenn, dann will sie keiner lesen, weil solche Sachen nicht zum normalen Sprachschatz gehören und nicht in normalem Kontext verwendet werden können, ohne jemanden zu beleidigen [sorry für die drei normalos :-].

          -M

          1. Btw, es kann doch nicht schaden, Wörter wie "Wich**r" oder "Arsc*l**h" oder "du blöde S**" zu sperren; normale User verwenden sie eh nicht, und wenn, dann will sie keiner lesen, weil solche Sachen nicht zum normalen Sprachschatz gehören und nicht in normalem Kontext verwendet werden können, ohne jemanden zu beleidigen [sorry für die drei normalos :-].

            Ich finde immerhin schon mal die Idee gut, auf solche Worte reagieren zu *können*.
            Eine andere Frage ist es nämlich, *wie* man darauf reagiert. Da gibt es neben der sofortigen Zensur im Posting-Skript ja auch noch andere Mittel (beispielsweise die automatische Generierung von E-Mails, entweder an den Betreiber des Forums oder/und an denjenigen, der das Posting gerade einträgt, so etwa ein freundliches "nanana, mußte das wirklich sein?").

            Es muß nicht immer sofort die Axt sein, aber das Erkennen einer kritischen Situation an sich kann IMHO nicht schaden.

      2. Hallo Marko,

        :-) Danke für die Antwort, aber wie würde der Code allgemein aussehen, d.h. für beliebige Zeichen?

        Wie waer's damit:

        ----------

        $Testwort = <STDIN>;     # Dein A..-Wort zum Beispiel
        $Teststring = <STDIN>;   # Dein zu untersuchender String

        for ($i = 0, $i < length($Testwort), $i++)

        {
        $Auswertung = substr($Testwort, $i, 1) . ".*";

        setzt hinter jedes Zeichen von $Testwort Punkt  und Stern

        }

        $Auswertung .= substr($Testwort, -1, 1);

        haengt noch das letzte Zeichen dran,

        das von der Schleife nicht abgearbeitet wurde

        den Punkt vor dem Gleichheitszeichen nicht uebersehen

        if ($Teststrung =~ /$Auswertung/i) 1:0;

        das i hinterm Schraegstrich, um Gross/Kleinschreibung zu ignorieren

        ----------

        Mit den Zeilen kannst Du jetzt jeden beliebigen Substring in jedem beliebigen String auf Deine angefragte Art testen.

        Beispiel:

        $Testwort = "aus";

        a) $Teststring = "Augenschmauss"     ergibt "enthalten"
        b) $Teststring = "auweia"                   ergibt nicht enthalten

        Funktioniert, ich hab's getestet.

        Viele Gruesse

        Beate Mielke

        1. kleine Korrektur

          anstatt

          if ($Teststrung =~ /$Auswertung/i) 1:0;

          $gefunden = ($Teststrung =~ /$Auswertung/i) ? 1 : 0;

          ich muss doch "richtig" bei Calocybe abschreiben ;-)

          1. Hallo Beate!

            kleine Korrektur

            Aehem... naja, da ist wohl noch eine etwas groessere Korrektur notwendig. Die Idee ist gut, aber an der Umsetzung musst Du echt mal noch ein bisschen arbeiten. Die Loesung verrate ich natuerlich noch nicht, will Dir ja nicht den Spass verderben... ;-)

            Aber danke fuer die Blumen...

            Mach's gut, Roland

            1. Hallo Roland,

              Aehem... naja, da ist wohl noch eine etwas groessere Korrektur notwendig. Die Idee ist gut, aber an der Umsetzung musst Du echt mal noch ein bisschen arbeiten. Die Loesung verrate ich natuerlich noch nicht, will Dir ja nicht den Spass verderben... ;-)

              Dazu faellt mir nur ein - peinlich, peinlich -

              Hoffentlich hat Marko das noch nicht ausprobiert.
              Ich haette die Variable $Auswertung vielleicht mal mittesten sollen. War also reines Glueck, dass alle Tests das richtige Ergebnis geliefert haben.

              So jetzt aber genug geredet, hier kommt die Korrektur:

              $Testwort = <STDIN>;    
              $Teststring = <STDIN>;

              len = length($Testwort);
              $Auswertung = "";

              for ($i = 0; $i < len-1; $i++)
              {
              $Auswertung .= substr($Testwort, $i, 1) . ".*";
              }

              $Auswertung .= substr($Testwort, -1, 1);
              $gefunden = ($Teststring =~ /$Auswertung/i) ? 1 : 0;

              Aber danke fuer die Blumen...

              gerne ;-)

              Beate, die sseehhrr hofft, dass jetzt alles richtig ist ...

              1. Hallo nochmal!

                Beate, die sseehhrr hofft, dass jetzt alles richtig ist ...

                Yepp, sieht doch schon viel besser aus, jetzt laeuft's bestimmt. :-) Hoffen wir nun, dass es das ist, was Marko wollte.

                Bis dann

      3. Hi,

        tja, dann will ich auch mal... :-)

        :-) Danke für die Antwort, aber wie würde der Code allgemein aussehen, d.h. für beliebige Zeichen?

        my $testwort = "Heini";
        my $teststring = "Du bist ein ganz besch*ssener Blödhei*i!";
        $testwort =~ s/(.)/($1\*).*?/g;
        my $gefunden = ($teststring =~ /$testwort/i);

        Have fun :-)

        Cheatah