SteveB: Regex - "Zeichen muß enthalten sein"

Hallo!

Ich komme mit einer Regex nicht zurecht.

Ich möchte, dass in einem String bestimmte Zeichen (mind. ein Kleinbuchstabe, mind. ein Großbuchstabe und mind. eine Ziffer von 1-9) enthalten sein müssen.

Mit if ($string!~/^[a-km-np-zA-KM-NP-Z2-9]+$/) {$flag=true;} wird $flag aber auch auf 'true' gesetzt, wenn der $string so aussieht "bauhaus".

Wo ist mein Fehler?

Danke.

  1. Moin,

    Wo ist mein Fehler?

    Meiner bescheidenen Meinung nach ist das mit einem Ausdruck so nicht möglich, jedenfalls nicht, wenn Kleinbuchstabe, Großbuchstabe und Ziffer nicht in fester Reihenfolge enthalten sein sollen.
    Eine Möglichkeit wäre also mit einzelnen RegEx-Ausdrücken erst nach den Anforderungen zu suchen.

    Grüße Marco

  2. Hi,

    Ich möchte, dass in einem String bestimmte Zeichen (mind. ein Kleinbuchstabe, mind. ein Großbuchstabe und mind. eine Ziffer von 1-9) enthalten sein müssen.

    Mit if ($string!~/^[a-km-np-zA-KM-NP-Z2-9]+$/) {$flag=true;} wird $flag aber auch auf 'true' gesetzt, wenn der $string so aussieht "bauhaus".

    Wo ist mein Fehler?

    Dich interessiert laut deinem Ausdruck lediglich, ob der komplette Text aus mindestens einem der in der Klasse aufgeführten Zeichen besteht (und aus nichts anderem).

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
  3. Tach!

    Ich möchte, dass in einem String bestimmte Zeichen (mind. ein Kleinbuchstabe, mind. ein Großbuchstabe und mind. eine Ziffer von 1-9) enthalten sein müssen.

    Dir ist die Reihenfolge egal, aber ich kenne keine Möglichkeit, einen Regex ohne Reihenfolgenbeachtung zu erstellen. Meiner Meinung nach könntest du dir lediglich die Zeichenklassen zu Nutze machen und mit drei und-verknüpften Regex (einer je Klasse) testen, ob je ein Vertreter der Klassen enthalten ist.

    dedlfix.

    1. Moin dedlfix,

      Dir ist die Reihenfolge egal, aber ich kenne keine Möglichkeit, einen Regex ohne Reihenfolgenbeachtung zu erstellen.

      Alle möglichen Reihenfolgen auflisten und oder-verknüpfen. Sind in dem Fall nur drei also 3*2*1 = 6 Möglichkeiten.

      Aber ja, ich würde auch drei unterschiedliche Regexe nutzen.

      LG,
       CK

      1. Hi,

        Dir ist die Reihenfolge egal, aber ich kenne keine Möglichkeit, einen Regex ohne Reihenfolgenbeachtung zu erstellen.
        Alle möglichen Reihenfolgen auflisten und oder-verknüpfen. Sind in dem Fall nur drei also 3*2*1 = 6 Möglichkeiten.

        3 positive Lookaheads, je einer für .*[a-z] und .*[A-Z] und .*[0-9], und dann noch normal auf [1]+$ (+ ggf. durch {x,y} für min/max-Länge prüfen.

        cu,
        Andreas

        --
        Warum nennt sich Andreas hier MudGuard?
        O o ostern ...
        Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.

        1. a-zA-Z0-9 ↩︎

        1. Tach!

          Dir ist die Reihenfolge egal, aber ich kenne keine Möglichkeit, einen Regex ohne Reihenfolgenbeachtung zu erstellen.
          Alle möglichen Reihenfolgen auflisten und oder-verknüpfen. Sind in dem Fall nur drei also 3*2*1 = 6 Möglichkeiten.

          Das hatte ich auch schon überlegt, aber da ich ohne das groß nachzuprüfen von 9 Möglichkeiten ausgegangen bin, hab ich die Idee gleich wieder verworfen. 6 geht ja grad noch so. Wenn nun aber noch ein Sonderzeichen dazukommt, sind wir schon bei 4*6 Möglichkeiten, und dann wird's langsam ungemütlich.

          3 positive Lookaheads, je einer für .*[a-z] und .*[A-Z] und .*[0-9], und dann noch normal auf [1]+$ (+ ggf. durch {x,y} für min/max-Länge prüfen.

          Warum willst du denn die restlichen Zeichen ausschließen? Es war nicht gefordert, nur a-zA-Z0-9 zuzulassen. Es soll nur jeweils ein Vertreter von diesen Klassen enthalten sein. Und wenn du zwischen explizit Anfang ^ und Ende $ angibst, wo soll da noch eine Assertion Platz finden?

          Ansonsten hatte ich das Handbuch so verstanden, dass PHP Assertions mit variabler Länge nicht mag. Hab mich da wohl geirrt, denn die Assertions-Idee scheint tatsächlich zielführend zu sein. Ich hab jedenfalls in meinen Versuchen mit /(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])/ keinen Gegenbeweis gefunden.

          dedlfix.


          1. a-zA-Z0-9 ↩︎

          1. Hi,

            Ansonsten hatte ich das Handbuch so verstanden, dass PHP Assertions mit variabler Länge nicht mag.

            Das gilt für Lookbehind assertions –

            Hab mich da wohl geirrt, denn die Assertions-Idee scheint tatsächlich zielführend zu sein. Ich hab jedenfalls in meinen Versuchen mit /(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])/ keinen Gegenbeweis gefunden.

            – dies hier sind aber Lookahead assertions.

            MfG ChrisB

            --
            RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
          2. Hi,

            3 positive Lookaheads, je einer für .*[a-z] und .*[A-Z] und .*[0-9], und dann noch normal auf [1]+$ (+ ggf. durch {x,y} für min/max-Länge prüfen.

            Warum willst du denn die restlichen Zeichen ausschließen? Es war nicht gefordert, nur a-zA-Z0-9 zuzulassen.

            Hatte ich übersehen, wäre aber ja durchaus üblich, daß ein Paßwort aus einem bestimmten Zeichensatz bestehen muß, und aus n von m Zeichengruppen mind. eins vorhanden sein muß.

            Ansonsten hatte ich das Handbuch so verstanden, dass PHP Assertions mit variabler Länge nicht mag.

            Wie Chris schon schrieb: bei Lookbehinds.
            Problem dabei ist, daß die Regex-Engine wissen will, ab welcher Position sie suchen soll. Bei Lookahead ist's klar: ab der aktuellen Position. Bei Lookbehind ist das nur klar, wenn die Assertion einen String fixer Länge hat (aktuelle Position minus fixe Länge).

            cu,
            Andreas

            --
            Warum nennt sich Andreas hier MudGuard?
            O o ostern ...
            Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.

            1. a-zA-Z0-9 ↩︎

            1. Tach!

              3 positive Lookaheads, je einer für .*[a-z] und .*[A-Z] und .*[0-9], und dann noch normal auf [1]+$ (+ ggf. durch {x,y} für min/max-Länge prüfen.
              Warum willst du denn die restlichen Zeichen ausschließen? Es war nicht gefordert, nur a-zA-Z0-9 zuzulassen.
              Hatte ich übersehen, wäre aber ja durchaus üblich, daß ein Paßwort aus einem bestimmten Zeichensatz bestehen muß, und aus n von m Zeichengruppen mind. eins vorhanden sein muß.

              Das mit dem Zeichensatz finde ich jedes Mal ziemlich unsinnig, wenn ich von einem Server dermaßen eingeschränkt werde. Was vergibt man sich denn als Admin, x-beliebige Zeichen zuzulassen? (Vorausgesetzt, man hat seine Kontextwechsel im Griff.)

              dedlfix.


              1. a-zA-Z0-9 ↩︎

              1. Moin Moin!

                Das mit dem Zeichensatz finde ich jedes Mal ziemlich unsinnig, wenn ich von einem Server dermaßen eingeschränkt werde.

                Ebenso Höchstlängen. Wenn sich jemand ein 50-stelliges Passwort quer durch alle Planes des Unicode merken kann, schön, dann darf er/sie gerne bei jedem Login 50 Zeichen in die Tastatur hacken und sich dabei die Finger verknoten. Mir ist das aus Entwickler- und Programmierersicht völlig egal, das Passwort geht zusammen mit einem zufälligen Salt sowieso durch irgendeine Hash-Funktion, und die stört sich an ein paar Bits mehr nicht. Natürlich kommt man irgendwo an eine Grenze, bei der affenartig lange Passworte zu einem DoS ausarten, also setze ich auch irgendwo eine Höchstlänge an, die aber weit jenseits von Gut und Böse ist. 256 oder 1024 Zeichen, oder etwas in der Richtung.

                Was vergibt man sich denn als Admin, x-beliebige Zeichen zuzulassen? (Vorausgesetzt, man hat seine Kontextwechsel im Griff.)

                Das dürfte eines der Hauptprobleme sein. Andererseits will man mit dem Passwort ja eigentlich nichts weiter machen als es in eine Hash-Funktion zu stopfen, und an deren anderem Ende fällt Bitsalat heraus, oft schon als Hexdump oder Base64 aufbereitet und damit unabhängig von der Eingabe völlig harmlos.

                Einen anderen Aspekt kannst Du aus dem ursprünglichen Pattern [a-km-np-zA-KM-NP-Z2-9] ablesen: l und 1 fehlen, O und 0, und lustigerweise auch L und o. Das sieht so aus, als sollte das Passwort druckbar und trotzdem nicht leicht zu verwechseln sein.

                Für sichere Passworte ist das völliger Blödsinn, das reduziert nur die Anzahl der möglichen Passworte und macht somit Angriffe leichter. Der wirklich einzige Punkt, wo ich solche Einschränkungen akzeptieren kann, ist bei auf Papier zugeschickten Initialpassworten, die exakt einmal benutzt werden können und dann geändert werden müssen.

                Alexander

                --
                Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".