Regexpr nur ein "Punkt" in String darf vorhanden sein

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

  • Regexpr nur ein "Punkt" in String darf vorhanden sein

    Hallo,

    ich hab Probleme mit einem Reg Expr der folgende Kriterien erfüllen muss: 4 bis 10 Zeichen, a-z0-9_ und nur maximal ein Punkt also {0,1} oder \.?

    Aber wie prüft man das in einem Reg Expr, [a-z0-9_]{4,10} wäre leicht, aber man kann dies ja nicht aufteilen, da der Punkt an beliebigen Stellen vorkommen darf.
    SQL Injection kitteh is...

  • #2
    IMHO nicht in einer Expression.

    Kommentar


    • #3
      Wie Tobiaz sagte, nicht darüber lösbar.

      - Explode beim Punkt
      - strlen der einzelnen Teile addieren
      - gucken, ob der Regex a-z0-9_ zutrifft und dann durchlassen.

      mfg

      Kommentar


      • #4
        Schau mal, ob dir das hier vielleicht weiter hilft.

        Grüße
        Nieder mit der Camel Case-Konvention

        Kommentar


        • #5
          Original geschrieben von Griecherus
          Schau mal, ob dir das hier vielleicht weiter hilft.

          Grüße
          Wüsste nicht wieso?

          Mal eine andere Frage, wenn [a-z_]{10} erlaubt sind, aber unterstriche niemals auf einander folgen dürfen, kann man dies in einer Reg Expr abfangen?
          Irgendwie rosten bei mir die reg expr schnell :/
          SQL Injection kitteh is...

          Kommentar


          • #6
            Erstes problem überhaupt schon gelöst?

            Was die sache mit den unterstrichen angeht, so würde ich einfach prüfen ob "__" nicht vorkommt. Fertig!

            Kommentar


            • #7
              Re: Regexpr nur ein "Punkt" in String darf vorhanden sein

              Original geschrieben von Seikilos
              Hallo,

              ich hab Probleme mit einem Reg Expr der folgende Kriterien erfüllen muss: 4 bis 10 Zeichen, a-z0-9_ und nur maximal ein Punkt also {0,1} oder \.?

              Aber wie prüft man das in einem Reg Expr, [a-z0-9_]{4,10} wäre leicht, aber man kann dies ja nicht aufteilen, da der Punkt an beliebigen Stellen vorkommen darf.
              Für den Fall, dass du den kompletten String prüfen willst und nicht nur einen Teilstring finden willst, der deinem Kriterium entspricht, könnte folgender RegExp helfen. Er enthält nur eine Lookahead-Assertion und ansonsten keine großartigen Tricks. Ein bisschen unhandlich ist er schon. Möglicherweise lässt er sich noch vereinfachen.

              PHP-Code:
              $pcre '/\A(?=[^\.]{0,10}(\.[^\.]{0,10})?)[a-z0-9_\.]{4,10}\z/';

              // test:
              $dot '.';
              // laengen von 3 bis 10 Zeichen
              for ($size 3$size <= 11; ++$size) {
                
              $base_haystack str_repeat('0'$size);
                
              // dot von position 0 bis letztmoegliche position
                // bei "position" -1 ohne punkt
                
              for ($dot_pos = -1$dot_pos strlen($base_haystack); ++ $dot_pos) {
                  
              $haystack $base_haystack;
                  if (isset(
              $haystack[$dot_pos])) {
                    
              $haystack[$dot_pos] = $dot;
                  }
                  
              $should_match =
                      (
              strlen($haystack) >= && strlen($haystack) <= 10 && strpos($haystack$dot) === strrpos($haystack$dot))
                      ? 
              0;
                  
              // meine persönliche debug-Hilfsfunktion
                  
              $has_match preg_match($pcre$haystack);
                  
              // debug_writefln('%s passt? %s richtig? %s', $haystack, $has_match, $has_match === $should_match);
                  // fuer Testausgabe im Browser
                  
              printf('len(%s) %s passt? %d richtig? %d<br />'strlen($haystack), $haystack$has_match$has_match === $should_match);
                }

              *nachtrag*
              Bitte zum Kopieren über die Zitieren-Funktion gehen. Bei der Darstellung unterschlägt dieses Board anscheinend einige Backslashes. *grml*

              Mal eine andere Frage, wenn [a-z_]{10} erlaubt sind, aber unterstriche niemals auf einander folgen dürfen, kann man dies in einer Reg Expr abfangen?
              Ja.

              Die Zauberworte heißen Lookahead-Assertion und Lookbehind-Assertion:

              PHP-Code:
              '/([a-z]|_(?!_)(?<!_)){10}/' 
              Zuletzt geändert von fireweasel; 30.12.2008, 23:34.
              Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

              Kommentar


              • #8
                Re: Regexpr nur ein &quot;Punkt&quot; in String darf vorhanden sein

                PHP-Code:
                function check($string) {
                  
                $len strlen($string);
                  return 
                $len >= && $len <= 10
                    
                && strpos($string".") === strrpos($string".") && preg_match("#^[a-z0-9_.]+$#"$string);

                Es musst nicht immer preg_* sein.
                Zuletzt geändert von ghostgambler; 01.01.2009, 15:31.

                Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

                bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
                Wie man Fragen richtig stellt

                Kommentar


                • #9
                  Danke Leute

                  hat so geklappt und ich hab was gelernt, wobei fireweasel n wenig mit Kanonen schießt, was?

                  Splitten war im Endeffekt die Lösung. Es ist nicht so, dass ich das nicht gekonnt hätte, aber an der Stelle, wo ich es benötige, gibt es nen RegExpr Validator der ein RegExpr nimmt, da hab ich gehoft, es mit einem reinen RegExpr zu lösen.
                  Nach TobiaZs Post (war auch der Meinung), habe ich einen eigenen, komplexen Validator gebaut.

                  Aber man hofft ja, noch n paar Tricks aufzuschnappen
                  SQL Injection kitteh is...

                  Kommentar


                  • #10
                    Re: Re: Regexpr nur ein &quot;Punkt&quot; in String darf vorhanden sein

                    Original geschrieben von Seikilos
                    Danke Leute

                    hat so geklappt und ich hab was gelernt, ...
                    Da hab ich so meine Zweifel. ;-)

                    wobei fireweasel n wenig mit Kanonen schießt, was?
                    Irgendwie werde ich den Eindruck nicht los, dass du schon mal vorfristig an der Silvesterbowle genascht hast. ;-)

                    Selbstverständlich bestand mein Lösungsvorschlag NUR aus dem Regulären Ausdruck -- also DER ERSTEN ZEILE. Der Rest des Quellcodes war NUR DER TEST, ob das Ganze auch wirklich funktioniert. Der war bewusst nur mit den "gewöhnlichen" PHP-Stringfunktionen realisiert. Wobei Menschen, die sich aus irgendwelchen Gründen vor den preg_...()-Funktionen fürchten, diese Variante ebenfalls benutzen können.

                    Ich habe jetzt spaßeshalber mal einen Geschwindigkeitsvergleich angestellt, zwischen meiner Variante und der Variante PHP-String-Funktionen plus simpler PCRE.

                    In Funktionen gepackt sehen beide Varianten so aus:
                    PHP-Code:
                    function strpos_n_strlen($txt) {
                      static 
                    $dot '.';
                      return (
                    strlen($txt) >= && strlen($txt) <= 10 && strpos($txt$dot) === strrpos($txt$dot) && preg_match('/\A[0-9a-z_.]+\z/'$txt)) ? TRUE FALSE;
                    }

                    function 
                    regex($txt) {
                      static 
                    $pcre '/\A(?=[^\.]{0,10}(?:\.[^\.]{0,10})?)[a-z0-9_\.]{4,10}\z/';
                      return (bool) 
                    preg_match($pcre$txt);

                    Jetzt siehst du hoffentlich auch, das meine Variante nicht umständlicher ist. Es sei denn, du hast schon wieder an der Bowle genascht ... ;-)

                    Das Ergebnis: In einigen (speziellen) Fällen ist der umständliche PHP-Weg tatsächlich schneller:
                    * Wenn der zu durchsuchende String zu kurz oder zu lang ist.
                    * Wenn mehr als ein Punkt vorhanden ist.

                    Wenn das aber nicht der Fall ist, und auch die strlen-strpos-Variante auf preg_match() zurückgreifen muss, um sicherzustellen, dass nur die angegebenen Zeichen vorhanden sind, dann ist meine Variante ca. 30 bis 60 Prozent schneller.

                    Einen String maximal zweimal zu durchsuchen ist ja auch schneller als das viermal zu machen (strlen(), strpos(), strrpos(), preg_match()).

                    Splitten war im Endeffekt die Lösung.
                    Wäre es zu viel verlangt, wenn du uns an deiner performanteren Lösung teilhaben lassen könntest? Irgendwie kann ich mir nicht vorstellen, dass explode() die Lösung darstellt: Da müssen Speicherbereiche neu zugewiesen und kopiert werden. Da muss sichergestellt werden, dass das Ergebnis des "Splits" nur 1 oder 2 Elemente haben muss. Und am Ende musst du wohl oder übel noch testen, ob auch wirklich nur die erlaubten Zeichen im String enthalten sind.

                    Es ist nicht so, dass ich das nicht gekonnt hätte, aber an der Stelle, wo ich es benötige, gibt es nen RegExpr Validator der ein RegExpr nimmt, da hab ich gehoft, es mit einem reinen RegExpr zu lösen.
                    Die Hoffnung wurde erfüllt ...
                    Nebenbei werde ich das Gefühl nicht los, das du eine bessere oder|und schnellere Lösung bekommen hättest, wenn du dein konkretes Problem in seiner Gesamtheit erläutert hättest und nicht nur in dieser verkürzten Variante.

                    Nach TobiaZs Post (war auch der Meinung), ...
                    Der äußerte lediglich seine "humble" (demütige|bescheidene) "Opinion" -- und lag daneben.

                    habe ich einen eigenen, komplexen Validator gebaut.
                    Warum? Bist dann nicht eher du derjenige, der mit Kanonen auf Spatzen schießt?

                    Aber man hofft ja, noch n paar Tricks aufzuschnappen
                    Ach komm, Lookahead-Assertions sind keine Tricks. Ich hoffe, du machst das nicht beruflich. ;-)
                    Falls doch: Es gibt da ein cooles Büchlein mit zwei lustigen Eulen vornedrauf -- die knapp 36 Euro hat der Chef sicher übrig.


                    Original geschrieben von ghostgambler
                    PHP-Code:
                    function check($string) {
                      
                    $len strlen($string);
                      return 
                    $len >= && $len <= 10
                        
                    && strpos($string".") == strrpos($string".") && preg_match("#^[a-z0-9_]+$"$string);

                    Es musst nicht immer preg_* sein.
                    Mal ganz davon abgesehen, dass du preg_match() benutzt ...

                    Dein PCRE funktioniert wahrscheinlich nicht, da fehlt irgendwie ein Begrenzer. Wenn man den hinzufügt, passt er natürlich niemals mehr auf einen String, in dem ein "." vorkommt. Und so ist entweder dein strpos()-vs-strrpos()-Vergleich oder preg_match() wahr -- die UND-Bedingung wird also nie erfüllt. Nebenbei liefern strpos() und strrpos() nicht nur numerische Ergebnisse, manchmal kommt auch ein FALSE zurück. Das wird dann bei deinem Vergleich implizit nach 0 gecastet. "." an Position 0 und kein "." gefunden wäre dann GLEICH.

                    Da kannst du auch gleich meine Testabfrage nehmen:
                    PHP-Code:
                    // ...
                     
                    $should_match =
                            (
                    strlen($haystack) >= && strlen($haystack) <= 10 && strpos($haystack$dot) === strrpos($haystack$dot))
                            ? 
                    0// oder: ? TRUE : FALSE;
                    // ... 
                    Das ändert aber nichts daran, dass damit der String 3-mal durchforstet wird. Ist irgendwie uneffektiv -- manchmal sollte man eben doch gleich preg_*() nehmen. ;-)
                    Zuletzt geändert von fireweasel; 31.12.2008, 17:26.
                    Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

                    Kommentar


                    • #11
                      Um zu zählen reicht eigentlich immer ein lookahead...
                      Beispiel: Regexp (ich hoffe ich habe keine Fehler gemacht )
                      Wie oben bereits geschrieben sind komplizierte reguläre Ausdrücke jedoch in solchen Fällen keineswegs zu empfehlen, wenn man Leistung und Schnelligkeit beachtet.
                      Eine weitere Möglichkeit mit einer weit einfacheren und weniger aufwendigen Regexp wäre:
                      PHP-Code:
                      $str "a_sx08t.rt";
                      $tmp explode("."$str3);
                      if(!isset(
                      $tmp[2]) && preg_match("/^[a-z0-9_\.]{4,10}$/i"$str)){
                       
                      // MATCH
                      }else{
                       
                      // NO MATCH

                      Vor dem Punkt im Regulären Ausdruck muss natürlich noch ein Backslash hin.

                      Kommentar


                      • #12
                        Lieber 3 String-Funktionen auf einen String als einen Regex von einer Zeile Länge.
                        Entwicklungs-Kosten sind deutlich höher als Hardware-Kosten.

                        Es geht übrigens auch ganz ohne preg:
                        PHP-Code:
                        function check($string) {
                          
                        $len strlen($string);
                          return 
                        $len >= && $len <= 10
                            
                        && strpos($string".") === strrpos($string".")
                            && 
                        strspn($string"abcdefghijklmnopqrstuvwxyz0123456789_.") == $len;


                        Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

                        bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
                        Wie man Fragen richtig stellt

                        Kommentar


                        • #13
                          Diese Idee mit dem strpos() === strrpos() finde ich echt kreativ!

                          Aber könnte man nicht einfach ein substr_count() == 1 machen?
                          Oder hat die andere Variante irgendwelche Vorteile?
                          PHP-Code:
                          function verrecke_elend()
                          {
                              die(
                          'Aaargh!');

                          Kommentar


                          • #14
                            Re: Re: Re: Regexpr nur ein &quot;Punkt&quot; in String darf vorhanden sein

                            Original geschrieben von fireweasel
                            Nebenbei liefern strpos() und strrpos() nicht nur numerische Ergebnisse, manchmal kommt auch ein FALSE zurück. Das wird dann bei deinem Vergleich implizit nach 0 gecastet. "." an Position 0 und kein "." gefunden wäre dann GLEICH.
                            Nebenbei machen wir uns jetzt bewusst, dass diese Einschränkung für den vorliegenden Fall vollkommen irrelevant ist.
                            Oder möchten Sie mir einen String kreieren, wo die eine Funktion einen Punkt an der ersten Stelle findet, die zweite Funktion dann jedoch keinen Punkt findet? Ich glaube ich vermag einwandfrei zu beweisen, dass es einen derartigen String nicht geben wird... entweder liefern beide Funktionen False, oder sie liefern beide einen numerischen Wert.

                            Übrigens, Forenregeln! Dein Code sprengt meine Auflösung von >1024.

                            Original geschrieben von CadEx
                            Diese Idee mit dem strpos() === strrpos() finde ich echt kreativ!

                            Aber könnte man nicht einfach ein substr_count() == 1 machen?
                            Oder hat die andere Variante irgendwelche Vorteile?
                            Kannst du auch verwenden.

                            Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

                            bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
                            Wie man Fragen richtig stellt

                            Kommentar


                            • #15
                              Re: Re: Re: Re: Regexpr nur ein &quot;Punkt&quot; in String darf vorhanden sein

                              Original geschrieben von ghostgambler
                              Kannst du auch verwenden.
                              Das würde ich wohl aus offensichtlichen Gründen tun.

                              Wenn ich den Topicersteller richtig verstanden habe, müsste es aber ein substr_count() <= 1 sein, das würde auch das Verhalten der str(r)pos()-Variante besser nachbilden.
                              PHP-Code:
                              function verrecke_elend()
                              {
                                  die(
                              'Aaargh!');

                              Kommentar

                              Lädt...
                              X