Michael: RegularExpressions und JS - Problem

Hallo,

ich will mit RegExp in einem Formular die Eingabe eines Namensfeldes prüfen. Die Eingabe soll Buchstaben aller möglichen Art sowie "-", "," und Leerzeichen erlauben.
Komischerweise funktioniert das nicht wie ich mir das vorstelle und ich verstehe einfach nicht warum folgendes nicht funktioniert:

var Vornamestr = document.formular.vorname.value;
var regexEinName = /[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ,-\ ]*/;
if (!regexEinName.test(Vornamestr))  {alert("falsch");}

Bin für jeden Tipp dankbar, ebenso auch für Links auf Tutorials, die die Thematik so erklären, dass auch Anfänger einen Einstieg bekommen (alles, was ich da bisher gefunden habe, glich immer eher einer formalen Sprach- und Syntaxdefinition denn einer verständlichen Erklärung).

Viele Grüße

Michael

  1. Hallo Michael.

    ich will mit RegExp in einem Formular die Eingabe eines Namensfeldes prüfen. Die Eingabe soll Buchstaben aller möglichen Art sowie "-", "," und Leerzeichen erlauben.

    Also \w?

    Komischerweise funktioniert das nicht wie ich mir das vorstelle und ich verstehe einfach nicht warum folgendes nicht funktioniert:

    Warum nimmst du nicht match()?

    Einen schönen Donnerstag noch.

    Gruß, Ashura

    --
    Selfcode: sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:) fl:( ss:) ls:[ js:|
    30 Days to becoming an Opera8 Lover -- Day 21: Toolbars
    Meine Browser: Opera 8.02 | Firefox 1.0.6 | Lynx 2.8.5 | Netscape 4.7 | IE 6.0
    [Deshalb frei! - Argumente pro freie Software]
    1. hi,

      ich will mit RegExp in einem Formular die Eingabe eines Namensfeldes prüfen. Die Eingabe soll Buchstaben aller möglichen Art sowie "-", "," und Leerzeichen erlauben.

      Also \w?

      nein, \w sind alle alphanummerichen zeichen und der unterstich.
      damit fehlen dir - und , und das leerzeichen; dafür hast du die ziffern zu viel.

      gruß,
      wahsaga

      --
      /voodoo.css:
      #GeorgeWBush { position:absolute; bottom:-6ft; }
      1. Hallo wahsaga und Ashura,

        und schon mal danke für die schnellen Antworten!

        nein, \w sind alle alphanummerichen zeichen und der unterstich.

        Ich hab gelesen, dass man mit Backslash einige "semantische Zeichen", bzw. einige Sonderzeichen "maskieren" kann und dachte, das "...,-\ ]" Komma, Minus und Leerzeichen bedeutet.(?)

        (Hab das aus einem Tutorial unter http://www.webreference.com/js/column5/index.html
        (welches das beste/lesbarste und halbwegs verständlichste war, das ich bisher gefunden hab). Dort steht auch, dass \w das gleiche ist wie [a-zA-Z_0-9], also genau wie wahsaga richtig feststellte:

        damit fehlen dir - und , und das leerzeichen; dafür hast du die ziffern zu viel.

        ... was mir da allerdings noch ein wenig unklar ist: die genau definition von alphanummerischen Zeichen, also ob da sowas wie ô o.ä. dabei wäre.)

        Warum nimmst du nicht match()?

        match(): "Durchsucht eine Zeichenkette mit Hilfe eines regulären Ausdrucks. Liefert Zeichenfolgen, auf die der reguläre Ausdruck passt, zurück. Erwartet als Parameter den regulären Ausdruck."

        Sowas will ich ja nicht zurück. Ich brauche ja eine Rückgabe von true oder false, um prüfen zu können, ob der String richtig oder falsch war... mit match() könnte ich mir das höchstens noch so vorstellen:
        if (meinString.match(meineRegEx) == "")
        aber was spricht gegen test() ?

        Ich verstehe leider nicht genau, an was meine Version von oben scheitert. Zum Beispiel wird "+Jörg*" nicht erkannt, das kann doch eigentlich nicht sein, oder?

        viele Grüße

        Michael

        1. Hallo Michael.

          Sowas will ich ja nicht zurück. Ich brauche ja eine Rückgabe von true oder false, um prüfen zu können, ob der String richtig oder falsch war...

          Naja?

          if(deinString.match(/.*/))  
          {  
            alert("Foo");  
          }
          

          Einen schönen Donnerstag noch.

          Gruß, Ashura

          --
          Selfcode: sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:) fl:( ss:) ls:[ js:|
          30 Days to becoming an Opera8 Lover -- Day 21: Toolbars
          Meine Browser: Opera 8.02 | Firefox 1.0.6 | Lynx 2.8.5 | Netscape 4.7 | IE 6.0
          [Deshalb frei! - Argumente pro freie Software]
          1. Hallo.

            Sowas will ich ja nicht zurück. Ich brauche ja eine Rückgabe von true oder false, um prüfen zu können, ob der String richtig oder falsch war...

            Naja?

            if(deinString.match(/.*/))

            {
              alert("Foo");
            }

              
            Anmerkung: korrekter wäre sicher [search()](http://de.selfhtml.org/javascript/objekte/string.htm#search), doch erspare ich mir so immer die Abfrage auf != -1.  
              
              
            Einen schönen Donnerstag noch.  
              
            Gruß, Ashura  
            
            -- 
            Selfcode: sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:) fl:( ss:) ls:[ js:|  
            [30 Days to becoming an Opera8 Lover](http://operalover.tntluoma.com/8/) -- [Day 21: Toolbars](http://operalover.tntluoma.com/8/day_21_toolbars)  
            Meine Browser: [Opera 8.02](http://my.opera.com/noctus/affiliate/download/) | Firefox 1.0.6 | Lynx 2.8.5 | Netscape 4.7 | IE 6.0  
            [\[Deshalb frei! - Argumente pro freie Software\]](http://deshalbfrei.org/)
            
            1. Hallo

              Naja?

              if(deinString.match(/.*/))

              {
                alert("Foo");
              }

                
              ????? - jetzt versteh ich gleich nur noch Bahnhof...  
              match() macht doch Folgendes: "Durchsucht eine Zeichenkette mit Hilfe eines regulären Ausdrucks. Liefert Zeichenfolgen, auf die der reguläre Ausdruck passt, zurück. Erwartet als Parameter den regulären Ausdruck."  
                
              wenn zb meinString = "meinString" ist, dann sieht doch die if-Abfrage letztendlich so aus:  
              `if("meinString")`{:.language-javascript}  
              Das würde mich doch höchstens weiterbringen, wenn ich wollte, dass immer foo ausgegeben wird.  
                
              Greets  
                
              Michael
              
          2. Tag,

            Hallo Michael.

            Sowas will ich ja nicht zurück. Ich brauche ja eine Rückgabe von true oder false, um prüfen zu können, ob der String richtig oder falsch war...

            Naja?

            if(deinString.match(/.*/))

            {
              alert("Foo");
            }

              
            Naja?  
            Bei .test() wird als Rückgabewert ein Boolean erzeugt. => 1 bit  
            Bei .match() wird als Rückgabewert ein String[] erzeugt. => viel mehr  
              
            Sicher kommt im Endeffekt das gleiche raus. In Hinsicht auf Effizienz ist also .test() zu Empfehlen.  
              
            Grüße,  
            Steffen.
            
    2. Warum nimmst du nicht match()?

      Ashura,
      Warum sollte er?

      Er will einen Wahrheitswert haben; den liefert test().

      Warum sollte er eine andere Methode nehmen, die nicht das tut, was er möchte, wenn es doch eine solche gibt, die genau das tut?

      Live long and prosper,
      Gunnar

      --
      „Weisheit ist nicht das Ergebnis der Schulbildung, sondern des lebenslangen Versuchs, sie zu erwerben.“ (Albert Einstein)
  2. var regexEinName = /[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ,-\ ]*/;
    if (!regexEinName.test(Vornamestr))  {alert("falsch");}

    Michael,
    Du prüfst, ob in Vornamestr eins der in [] angegebenen Zeichen beliebig oft (einschließlich null Mal) vorkommt.

    regexEinName.test(Vornamestr) wird wohl immer true sein, !regexEinName.test(Vornamestr) also immer false.

    Live long and prosper,
    Gunnar

    --
    „Weisheit ist nicht das Ergebnis der Schulbildung, sondern des lebenslangen Versuchs, sie zu erwerben.“ (Albert Einstein)
    1. Michael,
      Du willst prüfen, ob in Vornamestr ein „falsches“ Zeichen vorkommt. Also suchst du eben danach:

      var regexEinName = /[^a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ\,\-\ ]/;

      Null vorkommende „falsche“ Zeichen sagen dir gar nichts, deshalb darf kein * dahinter stehen. Auf ein + kannst du verzichten.

      Live long and prosper,
      Gunnar

      PS. Ich glaub nicht, dass du Komma und Leerzeichen im regulären Ausdruck maskieren musst:

      var regexEinName = /[^a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ,\- ]/;

      sollte es genauso tun.

      --
      „Weisheit ist nicht das Ergebnis der Schulbildung, sondern des lebenslangen Versuchs, sie zu erwerben.“ (Albert Einstein)
      1. Michael, nochwas:
        Du willst, „die Eingabe soll Buchstaben aller möglichen Art sowie "-", "," und Leerzeichen erlauben“, erlaubst aber nur lateinische Buchstaben aus Basic Latin und Latin-1 Supplement. [UNICODE]

        Du lässt Håkon zu, sperrst aber Łukasz und Jiři aus? Wenn du alle möglichen westeuropäischen Zeichen berücksichtigst, verdienen das die mittel- und osteuropäischen genauso. Wenigstens Latin Extended-A.

        Und Zeichen jenseits von U+007F lassen sich genauso zusammenfassen wie a-z. Dann sieht der reguläre Ausdruck so aus:

        var regexEinName = /[^a-zA-ZÀ-ÖØ-öø-ž,\- ]/;

        Live long and prosper,
        Gunnar

        --
        „Weisheit ist nicht das Ergebnis der Schulbildung, sondern des lebenslangen Versuchs, sie zu erwerben.“ (Albert Einstein)
        1. Hallo Gunnar,

          danke schon mal für Deine Mühen!

          Du lässt Håkon zu, sperrst aber Łukasz und Jiři aus? Wenn du alle möglichen westeuropäischen Zeichen berücksichtigst, verdienen das die mittel- und osteuropäischen genauso. Wenigstens Latin Extended-A.

          Ja klar, gutes Argument.

          Und Zeichen jenseits von U+007F lassen sich genauso zusammenfassen wie a-z. Dann sieht der reguläre Ausdruck so aus:

          Ah, das ist natürlich sehr praktisch, ich würde nämlich natürlich schon gern alle "Um/Sonderlaute" mitnehmen, wusste aber nicht wie.

          var regexEinName = /[^a-zA-ZÀ-ÖØ-öø-ž,\- ]/;

          Das gefällt mir sehr gut!
          Aber bedeutet das ^ am Anfang nicht, dass das Pattern hier dann nur gegen das  erste Zeichen in meinem String gematcht wird?

          Du prüfst, ob in Vornamestr eins der in [] angegebenen Zeichen beliebig oft (einschließlich null Mal) vorkommt.

          Aja, logisch. Da hatte ich offensichtlich einen Denkfehler.
          Habe jetzt mal Deine Tipps und ein paar Varianten ausprobiert, funktioniert aber leider immer noch nicht - dachte eigentlich, dass
          [a-zA-ZÀ-ÖØ-öø-ž,- ] hinhauen müsste, tat es aber nicht.
          zb. geht "+Jörg+" als richtig durch "+++" dagegen nicht.
          (Was mich dann noch mehr verwirrte, war, dass "+Jörg+" sogar gegen die Version mit ^ am Anfang durchging, was es meinem bisherigen Verständnis nach auf keinen Fall tun hätte dürfen, da es ja gleich beim + und doch eigentlich nur bei diesem scheitern hätte müssen???)

          Als möglichen Grund dafür kann ich mir nur vorstellen, dass die test()-Funktion true zurückliefert, sobald irgendeines der Zeichen in meinem String gematcht werden kann, egal, ob welche dabei waren die nicht gematcht wurden. Kann das sein?

          Viele Grüße

          Michael

          1. gudn tach Michael!

            var regexEinName = /[^a-zA-ZÀ-ÖØ-öø-ž,\- ]/;

            Das gefällt mir sehr gut!
            Aber bedeutet das ^ am Anfang nicht, dass das Pattern hier dann nur gegen das  erste Zeichen in meinem String gematcht wird?

            ja (das bedeutet es nicht). wenn das ^ das erste zeichen in einer zeichenklasse (also zwischen eckigen klammern []) ist, dann bedeutet es eine negation.

            [a-z] heisst in etwa "ein zeichen, das ein kleiner lateinischer buchstabe ist".

            [^a-z] heisst in etwa "ein zeichen, das kein kleiner lateinischer buchstabe ist".

            wenn du also einen string _negativ_ testest auf /[^a-z]/, dann bedeutet das, dass der string deine bedingungen erfuellt.

            prost
            seth

  3. Hallo Michael,

    Bin für jeden Tipp dankbar, ebenso auch für Links auf Tutorials, die die Thematik so erklären, dass auch Anfänger einen Einstieg bekommen

    Lies doch mal meine Anleitung

    Gruß, Andreas

    --
    SELFFORUM - hier werden Sie geholfen,
    auch in Fragen zu richtiges Deutsch
    1. Hallo Andreas,

      Lies doch mal meine Anleitung

      Gutes Tutorial! Hat sich sehr schön gelesen und die Möglichkeit, dass man das gelesene gleich ausprobieren kann ist genial.

      Nur versteh ich die Funktionsweise eine RE scheinbar immer noch nicht... ich hab irgendwo noch einen Denkfehler drin, den mir auch Dein Tutorial nicht austreiben konnte.

      Ich hab mir zum probieren mal folgendes konstruiert:
         var Vornamestr = document.formular.vorname.value;
         var regexEinName = /[a-zA-ZÀ-ÖØ-öø-ž,- ]/;
          alert(Vornamestr);
          var m = Vornamestr.match(/[a-zA-ZÀ-ÖØ-öø-ž,- ]/);
          alert ("match ist dann " + m);
          var s = Vornamestr.search(/[a-zA-ZÀ-ÖØ-öø-ž,- ]/);
          alert ("search ist dann " + s);
          var t = regexEinName.test(Vornamestr);
          alert ("und test ist dann " + t);

      Für "Jörg" bekomme ich zurück: m = J; s = 0; t = true;
      Erwartet hätte ich: m = "Jörg"; s = 0 (bzw. 2); t = true;
      Für "J+rg" bekomme ich das gleiche zurück wie für "Jörg" (m = J; s = 0; t = true;).
      Erwartet hätte ich: m = "Jrg"; s = -1 (bzw. 1); t = false;

      Kannst Du mir bitte sagen, warum die RE nur auf das erste Zeichen wirkt (bzw. warum zumindest in meinem Verständnis dieser Eindruck entsteht) und wie ich es formulieren muss, dass jedes Zeichen verglichen wird.
      (Ursprünglich hatte ich das ja mal so gelöst...
       var laenge = document.formular.vorname.value.length;
       for (i; i < laenge; i++)  {
      if (!(document.formular.vorname.value.charAt(i).match(/[-a-zA-Z...usw...]/)))  {usw;}
      ...und da war die Welt noch in Ordnung..., bis mir dann jemand, der schon programmiert hat, bevor ich auf der Welt war gesagt hat, dass ich die Schleife doch gar nicht brauche)

      Vielen Dank und viele Grüße

      Michael

      1. gudn tach Michael!

        Vornamestr.match(/[a-zA-ZÀ-ÖØ-öø-ž,- ]/);

        durchsucht den string nach dem ersten vorkommnis eines zeichens aus der angegebenen zeichenklasse [a-z...] und gibt dieses zurueck.
        bei Vornamestr=='hansi' wuerde 'h' zurueckgegeben werden.
        bei Vornamestr=='3:hansi' wuerde ebenfalls 'h' zurueckgegeben werden.
        bei einem string, der nur aus zeichen besteht, die nicht aus deiner zeichenklasse stammen z.b. ':!3{' koennte auch kein gefundenes zeichen zurueckgegeben werden.

        im gegensatz dazu:
        /[^a-zA-ZÀ-ÖØ-öø-ž,- ]/
        durchsucht den string nach dem ersten vorkommnis eines zeichens, das _nicht_ aus der angegebenen zeichenklasse [a-z...] stammt.
        falls so ein zeichen gefunden werden wuerde, wuesstest du, dass der string nicht erlaubt waere.

        du koenntest aber auch genausogut pruefen, ob der string von vorne (^) bis hinten ($) aus lauter zeichen besteht, die aus deiner zeichenklasse stammen.
        /[1]*$/
         ^ heisst anfang
                               * heisst "mindestens nullmal" das vorhergehende zeichen
                                $ heisst ende

        prost
        seth


        1. a-zA-ZÀ-ÖØ-öø-ž,- ↩︎

        1. Hallo seth

          prost

          Prost !
          ... und tausend Dank ! endlich funktionierts und ich glaub ich habs endlich ein bisschen kapiert wiso.

          Jetzt werd ich mir dann mal noch ein Getränk gönnen, das evtl. in Deiner Datenbank gelistet ist ;-)

          viele Grüße

          Michael