WernerK: Javascript Textfeld Dateiname überprüfen

0 48

Javascript Textfeld Dateiname überprüfen

WernerK
  • javascript
  1. 0
    Felix Riesterer
    1. 0

      immer diese Schlaumeier!

      Felix Riesterer
      1. 0
        WernerK
      2. 0
        Reinhard
  2. 0
    Der Martin
    1. 0
      WernerK
      1. 0
        Auge
      2. 0
        Felix Riesterer
      3. 0
        Der Martin
        1. 0
          WernerK
  3. 0
    Reinhard
    1. 1
      1unitedpower
      1. 0
        Gunnar Bittersmann
        1. 0
          1unitedpower
        2. 0
          Felix Riesterer
          1. 0
            1unitedpower
            1. 0
              Felix Riesterer
              1. 0
                1unitedpower
                1. 0
                  Felix Riesterer
                2. 0
                  WernerK
                  1. 0
                    Matthias Apsel
                    1. 0
                      WernerK
                    2. 0

                      Ja nee is’ klar: Der Nutzer ist schuld

                      Gunnar Bittersmann
                      • markdown
                      • zu diesem forum
                      1. 0
                        Matthias Apsel
                        1. 0
                          Gunnar Bittersmann
                  2. 0
                    1unitedpower
                    1. 0
                      WernerK
    2. 0
      Gunnar Bittersmann
      1. 0
        Reinhard
  4. 0
    WernerK
    1. 0
      Gunnar Bittersmann
      • html
      • javascript
      1. 0
        WernerK
        1. 0
          Matthias Apsel
          1. 0
            WernerK
          2. 0
            Gunnar Bittersmann
  5. 0

    Unterschied Schreibweise?

    WernerK
    1. 2
      dedlfix
      1. 0
        WernerK
        1. 3
          dedlfix
          1. 0
            WernerK
            1. 0
              dedlfix
              1. 0
                WernerK
            2. 0
              Der Martin
              1. 0
                dedlfix
                1. 0
                  Der Martin
                  1. 0
                    Matthias Apsel
                    1. 0
                      Der Martin

Hallo in einem Textfeld kann man einen Namen eingeben der später für einen Windows Dateinamen genommen wird. Ich will per Javascript nun nach gültigen Namen prüfen. Versucht habe ich es so.

function isValidFilename(fname) { var rexp = new RegExp(/[^\/:*?"<>|]/) return fname.replace(rexp, "") }

und im Textfeld dann: onkeyup="isValidFilename(this.value)"

Man kann aber trotzdem * ? oder andere ungültige Zeichen eingeben. Stimmt die Regex nicht?

Danke Gruss Werner

  1. Lieber WernerK,

    Stimmt die Regex nicht?

    ja.

    Du definierst eine character class mit dem Ausschlusszeichen '^':

    var rexp = new RegExp(/[^\/:*?"<>|]/)

    Dann willst Du die auszuschließenden Zeichen finden(?!) und ersetzen.

    return fname.replace(rexp, "")

    Deine RegExp findet nur das, was Du nicht ausgeschlossen hast, also alle erlaubten Zeichen. Deshalb kann replace() die verbotenen Zeichen nicht ersetzen, da diese ja nicht gefunden werden.

    Liebe Grüße,

    Felix Riesterer.

    1. Lieber Felix,

      was haste da wieder für einen Bockmist verzapft. Aber echt jetzt!

      Du definierst eine character class mit dem Ausschlusszeichen '^':

      var rexp = new RegExp(/[^\/:*?"<>|]/)

      Das stimmt nicht. Hier wird eine RegExp definiert, die keinen Inhalt hat. Der an RegExp() zu übermittelnde erste Parameter muss ein String sein, kein RegExp-Objekt:

      var rexp = new RegExp("[\\/:\*\?\"<>\|]"); // back slash vor dem quote nicht vergessen!
      

      Deshalb wurden die erlaubten Zeichen auch nicht ersetzt.

      Liebe Grüße,

      Felix Riesterer.

      1. Lieber Felix,

        Deshalb wurden die erlaubten Zeichen auch nicht ersetzt.

        Leider ändert sich auch mit deiner neuen Schreibweise nichts. Man kann trotzdem die verbotenen Zeichen eingeben bzw. sie werden nicht durch Leerzeichen ersetzt.

        Gruss Werner

      2. Hallo,

        Lieber Felix, was haste da wieder für einen Bockmist verzapft. Aber echt jetzt!

        Ja, aber diesesmal immer noch nicht ganz korrekt:

        var rexp = new RegExp("[\\/:\*\?\"<>\|]"); // back slash vor dem quote nicht vergessen!
        

        Deshalb wurden die erlaubten Zeichen auch nicht ersetzt.

        Du sprichst von "Zeichen" ... – Plural – aber,
        warum hast du vor nur ein einziges dieser Zeichen zu ersetzen?
        Hast du etwa ‚g‘ vergessen?

        Reinhard

  2. Hi,

    in einem Textfeld kann man einen Namen eingeben der später für einen Windows Dateinamen genommen wird. Ich will per Javascript nun nach gültigen Namen prüfen.

    das ist nicht ganz trivial. Sicher ist es ein guter Anfang, verbotene Zeichen auszuschließen, aber ob das genügt?

    Versucht habe ich es so.

    function isValidFilename(fname) { var rexp = new RegExp(/[^\/:*?"<>|]/) return fname.replace(rexp, "") }

    und im Textfeld dann: onkeyup="isValidFilename(this.value)"

    Schön - damit rufst du die Prüffunktion zwar bei jedem Tastendruck im Textfeld auf, kümmerst dich aber nicht um das Ergebnis.

    Man kann aber trotzdem * ? oder andere ungültige Zeichen eingeben.

    Natürlich. Du tust ja auch nichts dagegen.

    So long,
     Martin

    1. Hallo Martin, deine Antworten sind mir ein Rätsel. Kann man es nicht einfach mal etwas ausführlicher oder genauer erklären, so wie Felix?

      Schön - damit rufst du die Prüffunktion zwar bei jedem Tastendruck im Textfeld auf, kümmerst dich aber nicht um das Ergebnis.

      Was soll das heissen? Ich will doch erreichen das im Textfeld keine unerlaubten Zeichen drin sind und diese dann auch nicht gespeichert werden.

      Natürlich. Du tust ja auch nichts dagegen.

      Auch diese Aussage ist mir schleierhaft. Wenn ein Fehler in der Regex ist dann kannst du es doch sagen oder?

      Gruss werner

      1. Hallo

        Hallo Martin, deine Antworten sind mir ein Rätsel. Kann man es nicht einfach mal etwas ausführlicher oder genauer erklären, so wie Felix?

        Schön - damit rufst du die Prüffunktion zwar bei jedem Tastendruck im Textfeld auf, kümmerst dich aber nicht um das Ergebnis.

        Was soll das heissen? Ich will doch erreichen das im Textfeld keine unerlaubten Zeichen drin sind und diese dann auch nicht gespeichert werden.

        Du tust aber, wie Martin schon sagte, nichts dafür. Deine Funktion aus diesem Posting, neu formatiert.

        function isValidFilename(fname) {
            var rexp = new RegExp(/[^\/:*\?"<>|]/)
            return fname.replace(rexp, "")
        }
        

        Du definierst einen Rückgabewert. Der besteht aus dem Eingabestring mit den evtl. gelöschten Zeichen. Du rufst deine Funktion auf …

        onkeyup="isValidFilename(this.value)"
        

        Natürlich. Du tust ja auch nichts dagegen.

        Auch diese Aussage ist mir schleierhaft.

        … und verarbeitest den Rückgabewert nicht. Es steht also nachher der gleiche String im Formularfeld, wie vorher, weil er nicht mit dem Ergebnis des Funktionsaufrufs ersetzt wird. Wenn du die Funktion nicht an mehreren Stellen einsetzt, kannst du den String auch innerhalb der Funktion überschreiben. Willst du die Funktion am mehreren Stellen einsetzen, musst du dazu noch das Element, welches bearbeitet werden soll, als Parameter an die Funktion übergeben.

        Dass es für den Benutzer des Formulars verwirrend sein kann, dass einzelne, soeben eingegebene Zeichen stante pede wieder verschwinden, steht auf einem anderen Blatt.

        Tschö, Auge

        --
        Es schimmerte ein Licht am Ende des Tunnels und es stammte von einem Flammenwerfer.
        Terry Pratchett, „Gevatter Tod“
      2. Lieber WernerK,

        Martin wollte Dich darauf hinweisen, dass beim Abschicken des Formulars (beim "submit"-Event) keinerlei JavaScript-Mechanismus die Gültigkeit des Namens überprüft und gegebenenfalls das Abschicken unterbricht. Ein Hinweis an den User ist wohl auch nicht vorgesehen...

        Martin schrieb:

        Schön - damit rufst du die Prüffunktion zwar bei jedem Tastendruck im Textfeld auf, kümmerst dich aber nicht um das Ergebnis.

        Der Rückgabewert Deiner Funktion bewirkt genau was...?

        Liebe Grüße,

        Felix Riesterer.

      3. Mahlzeit,

        deine Antworten sind mir ein Rätsel.

        das ist erstmal nichts Schlechtes. ;-)

        Kann man es nicht einfach mal etwas ausführlicher oder genauer erklären, so wie Felix?

        Im Prinzip ja - normalerweise versuche ich aber, nicht direkt die Lösung aufzuzeigen, sondern den Fragesteller auf seine Fehler hinzuweisen, so dass er mit etwas Nachdenken versteht, wo es klemmt und warum. Entschuldige bitte, wenn ich da bei dir zu viel "Insight", sprich Fachwissen und Verständnis voraussetze.

        Schön - damit rufst du die Prüffunktion zwar bei jedem Tastendruck im Textfeld auf, kümmerst dich aber nicht um das Ergebnis.

        Was soll das heissen? Ich will doch erreichen das im Textfeld keine unerlaubten Zeichen drin sind und diese dann auch nicht gespeichert werden.

        Genau. Ob dein Regex an sich korrekt ist, habe ich jetzt noch gar nicht betrachtet; dein Fehler liegt schon im Ansatz.

        Du hast eine Funktion isValidFilename(), die als Parameter den ursprünglichen, eventuell ungültigen Dateinamen bekommt, und als Funktionsergebnis den korrigierten Namen liefert (vorausgesetzt, die Funktion selbst arbeitet korrekt).
        Anmerkung: Eine Funktion, die is...() benannt ist, fragt zumindest dem Namen nach eigentlich nach einer Ja/Nein-Information, und man würde ein boolsches Ergebnis (true/false) erwarten. So gesehen ist deine Funktion unpassend benamst. Aber das nur nebenbei.

        Da, wo du die Funktion aufrufst, im keyup-Eventhandler, nimmst du das Ergebnis aber gar nicht entgegen!

        Natürlich. Du tust ja auch nichts dagegen.

        Auch diese Aussage ist mir schleierhaft. Wenn ein Fehler in der Regex ist dann kannst du es doch sagen oder?

        Nein, Regex ist nicht meine starke Seite, da halte ich mich raus. Meine Kritik galt ausschließlich deiner fehlerhaften Programmlogik. Du müsstest zumindest das Funktionsergebnis nach dem Aufruf wieder in das Textfeld schreiben.

        Vom Bedienungskomfort her finde ich das aber auch nicht schön, denn erstens flackert der Inhalt des Eingabefelds dann bei jedem Tastendruck, zweitens ist es eventuell irritierend, wenn man beispielsweise ein ':' drückt und es passiert nichts.
        Ich persönlich würde die Validierung der Eingabe erst beim Absenden des Formulars machen (also onsubmit), und dann ggf. den Nutzer informieren, dass der eingegebene Dateiname ungültige Zeichen enthält.

        Ich hoffe, die Erklärung war jetzt ein wenig besser.

        So long,
         Martin

        1. Hallo Martin,

          Ich hoffe, die Erklärung war jetzt ein wenig besser.

          vieeeeel besser :-)

          Tausend Dank Ja ich glaube ich muss das nochmals umbauen und vielleicht erst beim Submit eine Meldung machen.

          viele Grüße Werner

  3. Hallo,

    so geht es:

    input.addEventListener('input', function() {
        var v = this.value,
            n = v.replace(/[\\\/:*\?"<>|]/g, '');
        if (n != v)
          this.value = n;
    });
    

    Reinhard

    1. input.addEventListener('input', function() {
          var v = this.value,
              n = v.replace(/[\\\/:*\?"<>|]/g, '');
          if (n != v)
            this.value = n;
      });
      

      Die Lösung stellt eine Barriere für Meschen dar, die auf einen Screenreader angewiesen sind. Es geht auch viel einfacher:

      <input pattern="^[^\/:*\?\u0022<>|]+$">
      
      1. @@1unitedpower

        Die Lösung stellt eine Barriere für Meschen dar, die auf einen Screenreader angewiesen sind.

        Du meinst, denen müsste der geänderte Inhalt nochmal vorgelsen werden?

        Es geht auch viel einfacher:

        <input pattern="^[^\/:*\?\u0022<>|]+$">
        

        Rettet die Katzen! (Das für CSS Gesagte gilt auch für HTML.)

        LLAP 🖖

        --
        Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
        1. Die Lösung stellt eine Barriere für Meschen dar, die auf einen Screenreader angewiesen sind.

          Du meinst, denen müsste der geänderte Inhalt nochmal vorgelsen werden?

          Irgendeine Form von Feedback wäre zumindest angebracht, über die genaue Form könnte man streiten, oder man delegiert diese Aufgabe an den User agent.

        2. Lieber Gunnar,

          ich verstehe die doppelte Verneinung hier nicht:

          <input pattern="^[^\/:*\?\u0022<>|]+$">
          

          Nach meinem Verständnis bedeutet das: Inhalt muss matchen, dass kein Zeichen der character class vorkommt, die kein , :, *, ?, ", <, > oder | enthalten darf.

          Habe ich das falsch verstanden, oder einen Denkfehler gemacht?

          Liebe Grüße,

          Felix Riesterer.

          1. ich verstehe die doppelte Verneinung hier nicht:

            Das erste Circumflex steht für den Beginn der Zeichenkette, nicht für die Komplementbildung einer Zeichenklasse.

            1. Lieber 1unitedpower,

              Das erste Circumflex steht für den Beginn der Zeichenkette, nicht für die Komplementbildung einer Zeichenklasse.

              also passt Gunnars Lösungsvorschlag nur beim ersten Zeichen, nicht aber bei allen restlichen, die man als Dateinamen eingeben kann.

              Liebe Grüße,

              Felix Riesterer.

              1. also passt Gunnars Lösungsvorschlag nur beim ersten Zeichen, nicht aber bei allen restlichen, die man als Dateinamen eingeben kann.

                Nein, der Ausdruck liest sich wie folgt:

                Von Anfang ^ bis Ende $ müssen alle vorkommenden Zeichen aus der Zeichenklasse [...] stammen, wobei die Zeichenkette mindestens 1 Zeichen lang sein muss, aber ansonsten beliebig lang sein darf +. Die angesprochene Zeichenklasse enthält alle Zeichen, die nicht ^ die Folgenden sind /:*?"<>|

                ^[^\/:*\?\u0022<>|]+$
                

                Du kannst ja selber mal Rumprobieren: http://jsfiddle.net/brq5jbvw/

                1. Lieber 1unitedpower,

                  Von Anfang ^ bis Ende $ müssen alle vorkommenden Zeichen aus der Zeichenklasse [...] stammen, wobei die Zeichenkette mindestens 1 Zeichen lang sein muss, aber ansonsten beliebig lang sein darf +. Die angesprochene Zeichenklasse enthält alle Zeichen, die nicht ^ die Folgenden sind /:*?"<>|

                  jaja, ich sehe ein, dass ich's einfach nicht kapiert hatte. Aber aus kindischem Trotz muss ich jetzt eben trotz-dem nachtreten:

                  Wenn /:*?"<>| nicht erlaubt sind, wie sieht es dann aus mit '$? Dachte bei Windoof würde das Dollarzeichen zum visuellen Verschwinden führen...?

                  Liebe Grüße,

                  Felix Riesterer.

                2. Also ehrlich gesagt blicke ich da jetzt nicht mehr durch vor so vielen unterschiedlichen Lösungen :-) Einmal: [1]+$

                  Was macht denn hier das "\u0022" ? Und warum hier ^[^ ? Das erste ^ bedeutet doch Stringanfang und das zweite ^ Negierung also Zeichen die nicht erlaubt sind oder?

                  Dann: /[\/:*?"<>|]/g

                  Warum hier dreimal \\ ?

                  Auch klappt bei mir dieses Fiddle nicht. http://jsfiddle.net/brq5jbvw/

                  Ich kann hier eingeben was ich will auch "*?. Alles ist erlaubt. Oder mach ich was falsch?

                  Gruss Werner


                  1. ^/:*?\u0022<>| ↩︎

                  1. Hallo WernerK,

                    Warum hier dreimal \\ ?

                    Der Backslash und einige andere Zeichen haben sowohl in der hier verwendeten Kramdown-Syntax als auch bei den regulären Ausdrücken eine Sonderbedeutung. Deshalb kann sich sichtbare Nachrichteninhalt vom Inhalt im Textfeld unterscheiden.

                    Das zielführendste ist, solche reguläre Ausdrücke mittels Backticks (``) als Code auszuzeichnen.

                    Bis demnächst
                    Matthias

                    --
                    Signaturen sind bloed (Steel) und Markdown ist mächtig.
                    1. ok, danke, Die Frage ist aber warum in meiner Variante trotzdem der Backslash erlaubt ist? Selbst wenn ich es mit drei \\ versuche, ist er erlaubt.

                      var rexp = new RegExp("[\\/:\*\?\"<>\|]"); // back slash vor dem quote nicht vergessen!
                        if(!fname.match(rexp))  
                        {  
                        //alle OK  
                        }  
                        else  
                        {  
                        alert('Keine gültige Zeichen sind < > ? " : | \ / *'); 
                        }
                      

                      Gruss Werner

                    2. @@Matthias Apsel

                      Warum hier dreimal \\ ?

                      Dreimal? Zweimal?

                      Der Backslash und einige andere Zeichen haben sowohl in der hier verwendeten Kramdown-Syntax als auch bei den regulären Ausdrücken eine Sonderbedeutung. Deshalb kann sich sichtbare Nachrichteninhalt vom Inhalt im Textfeld unterscheiden.

                      Deshalb ist der Zwang, Kramdown zu verwenden, völlig an den Anforderungen dieses Forums vorbei implementiert.

                      Das zielführendste ist, solche reguläre Ausdrücke mittels Backticks (``) als Code auszuzeichnen.

                      Das zielführendste ist, diesen Forums-Bug zu beheben.

                      LLAP 🖖

                      --
                      Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
                      1. Hallo Gunnar Bittersmann,

                        Ja nee is’ klar: Der Nutzer ist schuld [Dein Betreff]

                        Schade, dass du dies aus meiner Nachricht liest.

                        Bis demnächst
                        Matthias

                        --
                        Signaturen sind bloed (Steel) und Markdown ist mächtig.
                        1. @@Matthias Apsel

                          Ja nee is’ klar: Der Nutzer ist schuld [Dein Betreff]

                          Schade, dass du dies aus meiner Nachricht liest.

                          „Deshalb kann sich sichtbare Nachrichteninhalt vom Inhalt im Textfeld unterscheiden. Das zielführendste ist, solche reguläre Ausdrücke mittels Backticks (``) als Code auszuzeichnen.“

                          Das hat schon was von „Der Nutzer ist schuld, wenn er Code nicht als solchen auszeichnet und sich deshalb der sichtbare Nachrichteninhalt vom Inhalt im Textfeld unterscheidet.“

                          Vielleicht etwas überspitzt, aber irgendwie muss man ja die Aufmerksamkeit auf dieses Problem lenken, wenn es nicht als solches wahrgenommen wird.

                          Und ich hab vernommen, dass CK kaum Zeit hat, das zu beheben, und <I> verteilt hat.

                          LLAP 🖖

                          PS: Ich hätte hier gerne das Posting berichtigt, aber meine Zeit war schon abgelaufen. Aber über die Sinn- oder Unsinnigkeit dieser Zeitbeschränkung wird auch schon andernorts diskutiert.

                          --
                          Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
                  2. Also ehrlich gesagt blicke ich da jetzt nicht mehr durch vor so vielen unterschiedlichen Lösungen :-)

                    Die Essenz meines Vorschlags ist, nicht JavaScript für etwas zu benutzen, dass in HTML schon in besserer Form existiert. Der reguläre Ausdruck musste sozusagen als Nebenwirkung angeglichen werden: Er wird nun nicht mehr benutzt, um unerlaubte Zeichen zu löschen, sondern um zu testen, ob die gegebene Zeichenkette keine unerlaubten Zeichen enthält.

                    Einmal: ^[^\/:*\?\u0022<>|]+$

                    Was macht denn hier das "\u0022" ?

                    Das steht für das doppelte Anführungszeichen, da der reguläre Ausdruck in ein HTML-Attribut eingeschlossen wird und das Attribut selber von Anführungszeichen begrenzt wird, muss es als Sonderzeichen in diesem Kontext maskiert werden.

                    Und warum hier ^[^ ? Das erste ^ bedeutet doch Stringanfang und das zweite ^ Negierung also Zeichen die nicht erlaubt sind oder?

                    Dann: /[\\\/:*\?"<>|]/g

                    Warum hier dreimal \\ ?

                    Das stammt nun nicht von mir, aber bei diesem reguläre Ausdruck wird wohl auch der Backslash gematcht, daher die ersten beiden Backslashes, anschlißend wird auch der gewöhnliche Slash gematcht, deshalb der dritte Backslash. Ob das sein muss, und ob auch das Dollarzeichen gematcht werden muss, wie Felix meint, kann ich nicht aus dem FF sagen, das sollte aber mit einer kurzen Recherche zu beantworten sein.

                    Auch klappt bei mir dieses Fiddle nicht. http://jsfiddle.net/brq5jbvw/

                    Ich kann hier eingeben was ich will auch "*?. Alles ist erlaubt. Oder mach ich was falsch?

                    Wenn du ein nicht-erlaubtes Zeichen eingibst, sollte das Feld einen roten Rahmen erhalten, weil es vom Browser als ungültig erkannt wird. Wenn du versuchen würdest das Formular in diesem Zustand abzuschicken, würde der Browser das Absenden verweigern bis alle Daten korrekt ausgefüllt worden sind. Dabei informiert der Browser auch evtl. angeschlossene assistive Software, so dass u.a. auch blinde Menschen den Fehler wahrnehmen können. Du hast außerdem die Möglichkeit mit CSS und den Pseudoklassen :valid und :invalid selber gestalterisch tätig zu werden, um das Surferlebnis deiner Nutzer noch zu verbessern. Das Beispiel ist fern ab von vollständig, es sollte nur dazu dienen, mit dem regulären Ausdruck zu spielen, nicht um als Musterbeispiel für eine gelungene Formular-Validierung zu dienen.

                    1. Ganz herzlichen Dank für die tolle und ausführliche Erklärung!

                      Gruss Werner

    2. @@Reinhard

      input.addEventListener('input', function() {
          var v = this.value,
              n = v.replace(/[\\\/:*\?"<>|]/g, '');
          if (n != v)
            this.value = n;
      });
      

      Wozu die if-Abfrage? Die würde ja nur Sinn machen, wenn eine Abfrage deutlich „billiger“ wäre als eine Zuweisung. Das glaub ich hier aber nicht. Also kann man auch in jedem Fall this.value mit n überschreiben.

      Die Zuweisungen zu v und n kann man aber einsparen und das Ganze gleich als Einzeiler notieren:

      input.addEventListener('input', function() {
          this.value = this.value.replace(/[\\\/:*\?"<>|]/g, '');
      });
      

      LLAP 🖖

      --
      Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
      1. Hallo,

        Wozu die if-Abfrage?

        Hmm, tatsächlich. Ich habe anfangs das keyup Event übernommen. Bei jenem Event wird die Funktion ja auch aufgerufen, wenn man Shift oder so etwas drückt. Da erschien es mir eleganter zu schauen, ob sich etwas geändert hat, anstatt wahllos bei jedem Tastendruck neu ins input.value zu schreiben. Habe es erst am Ende noch umgeändert, weil es mir sinnvoller erschien.

        Reinhard

  4. Darf ich hier nochmals nachhaken? ich hatte die Funktion jetzt so geändert das zuerst geprüft wird und dazu eine Meldung kommt welche Zeichen gültig bzw. nicht gültig sind. Danach erfolgt ein Replace. Vielleicht ändere ich das auch noch ganz ohne Replace und erst beim Submit.

    Es funktioniert auch soweit bis auf den Backslash
    Der kann weiterhin eingegeben werden. ich verstehe nur nicht so ganz warum. Das müsste doch mit dem "\" ganz am Anfang abgefangen sein oder?

    function isValidFilename(fname)
    { 
      var rexp = new RegExp("[\\/:\*\?\"<>\|]"); // back slash vor dem quote nicht vergessen!
      if(!fname.match(rexp))  
      {  
      //alle OK  
      }  
      else  
      {  
      alert('Keine gültige Zeichen sind < > ? " : | \ / *'); 
      }
      var correctstring =  fname.replace(rexp, "")
      $('#txt_input').val(correctstring);
    }
    

    Gruss Werner

    1. @@WernerK

      ich hatte die Funktion jetzt so geändert das[s] […]

      Du hattest aber mitgelesen, dass die sinnvolle Änderung der Funktion deren Abschaffung ist?

      LLAP 🖖

      --
      Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
      1. Hallo Gunnar,

        Du hattest aber mitgelesen, dass die sinnvolle Änderung der Funktion deren Abschaffung ist?

        Ja gelesen ja. Nur nicht so recht verstanden was das mit dem Screenreader auf sich hat und was hier jetzt anders passiert? Und wie gesagt: Die Lösung mit dem CSS bzw. pattern funktioniert bei mir im JSFiddle nicht. Ich kann weiterhin eingeben was ich will.

        Gruss Werner

        1. Hallo WernerK,

          Und wie gesagt: Die Lösung mit dem CSS bzw. pattern funktioniert bei mir im JSFiddle nicht. Ich kann weiterhin eingeben was ich will.

          eingeben ja, aber kannst du das Formular auch abschicken?

          Bis demnächst
          Matthias

          --
          Signaturen sind bloed (Steel) und Markdown ist mächtig.
          1. Hallo Matthias,

            eingeben ja, aber kannst du das Formular auch abschicken?

            Ahh, Im Beispiel fehlt ein Submit aber ja jetzt habe ich es gesehen. Im Fehlerfall wird der Input Rahmen rot und ein Submit wird dann vermutlich nicht mehr möglich sein.

            Danke Gruss Werner

          2. @@Matthias Apsel

            eingeben ja, aber kannst du das Formular auch abschicken?

            Im Safari (zumindest bis 8) leider ja. Ist dieser Bug im 9er eigentlich endlich gefixt?

            LLAP 🖖

            --
            Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
  5. Hallo liebe Helfer, vielen Dank nochmals für die Hilfe und Vorschläge. Vermutlich werde ich dann doch die Variante mit CSS und der Klasse "invalid" umsetzen. Ich habe trotzdem noch eine letzte Frage nur zum Verständnis und um was zu lernen :-)

    Warum muss man beim "match" bzw der Schreibweise "[\\/:*?"<>|]" anders maskieren als unten beim "replace"? Liegt das am (" ") also dem Hochkomma? Normalerweise reicht doch ein Backslash um die Zeichen * ? " | \ / zu maskieren. Offensichtlich braucht man aber 3 Backslash für den \ selbst? Nur so wird er erkannt. var rexp = new RegExp("[\\/:*?"<>|]"); if(!fname.match(rexp))

    Und warum muss man hier den * " und | nicht maskieren und braucht zudem noch das "g" am Schluss?

    var correctstring = fname.replace(/[\\\/:*\?"<>|]/g, '');

    vielen Dank Gruss Werner

    1. Tach!

      Offensichtlich braucht man aber 3 Backslash für den \ selbst? Nur so wird er erkannt.

      Das Grundübel ist das Vermischen von Code und Nutzdaten. Man braucht nun Regeln, wie man zwischen den Nutzdaten Code erkennen kann oder auch andersrum, wie man Nutzdaten innerhalb von Code unterbringen kann, ohne dass es da Interpretationsspielraum gibt. Man verwendet dazu Maskierungen. Ein bestimmtes Zeichen zeigt an, dass der Autor grad was aus dem anderen Kontext meint.

      Und um die Sache nicht ganz so einfach zu lassen, kann man Code und Nutzdaten verschiedene Systeme miteinander vermischen. Für das eine System sollen bestimmte Zeichen Code bzw. Nutzdaen sein, das andere soll sie nur durchreichen, darf also keinen Code in Nutzdaten erkennen. Da bleibt es dann nicht aus, dass man mehrfach maskieren muss. Das eine System interpretiert Maskierzeichen weg und das andere braucht für seine Verarbeitung auch noch welche. Und dann kommen da 3 oder 5 oder eine beliebig andere Zahl an Maskierzeichen hintereinander zu stehen.

      Das ist ähnlich wie beim Warenversand. Das Produkt wird verpackt, bekommt einen Versandkarton drumherum, der kommt auf eine Palettenkiste, die in einen großen Container gestellt wird - und ab geht die Reise. Am anderen Ende muss man das Zeug in umgekehrter Reihenfolge wieder auspacken. Der Logistiker nimmt die Palette aus dem Container, der Großhändler die Versandkartons aus der Palette, der Einzelhändler die verpackten Produkte aus dem Versandkarton und der Kunde das Produkt aus der Verpackung. Hier nun hat man aber spezielle Verpackungen, beim Programmieren nimmt man hingegen immer wieder dieselben Zeichen. Und da sind die Grenzen der Zuständigkeiten nicht mehr so eindeutig wie beim Versand.

      dedlfix.

      1. Hallo dedlfix,

        ....und wenn wir mal jetzt wieder weggehen vom Logisitker und von den Paletten und es ganz konkret an dem Beispielcode festmachen? :-) Vielleicht ist es ja dann doch auch für andere "Nicht so tief drin Experten" ersichtlicher?

        Diese Regex

        new RegExp("[\\\\/:\*\?\"<>\|]")
        

        und dann wiederum

        replace(/[\\\/:*\?"<>|]/g, '')
        

        scheinen das gleiche zu bewirken (Also von der regex her) Also im ersten Beispiel brauchte man \ für die Masierung des Backslash und für / * ? " | jeweils ein \

        Bei Replace ist das wieder ganz anders. Liegt das nun weil beim Replace Code mit Slash / begrenzt wird und oben mit " ? Gruss Werner

        1. Tach!

          ....und wenn wir mal jetzt wieder weggehen vom Logisitker und von den Paletten und es ganz konkret an dem Beispielcode festmachen? :-) Vielleicht ist es ja dann doch auch für andere "Nicht so tief drin Experten" ersichtlicher?

          Es kommt auf den Kontext an, in dem man sich befindet, um ein Stück Code korrekt zu interpretieren. Wenn du ein Stück Code aus seinem Kontext herausnimmst, und es irgendwo anders einfügst, kommt es damit auch in einem anderen Kontext zu liegen. Wenn ich es nun gemäß diesem neuen Kontext interpretiere, kommt vermutlich nicht mehr das raus, was rauskäme, wenn ich es nach den Regeln des alten läse. Wenn der Javascript-Code als String in PHP stünde, kämen noch mehr Maskierungen hinzu. Wenn du dann den PHP-Teil wegließest, sehe ich zu viele Maskierungzeichen, die sonst von PHP vertilgt werden würden, bevor das Javascript sie zu Gesicht bekommt. Das nur mal am Rande, denn diese Problematik liegt hier nicht vor.

          new RegExp("[\\\\/:\*\?\"<>\|]")
          

          Ich sehe hier einen Stringanfang ". Dann kommt (die Klammer ignorierend) ein , welches dem folgenden Zeichen eine besondere Bedeutung gibt. Das folgende \ heißt in dem Fall, dass genau ein \ wörtlich gemeint ist. Die zwei \\ fallen damit zu einem \ zusammen. Mit den nächsten beiden passiert dasselbe. Der entstehende String ist also letztlich [\\/:*?"<>|]

          Die anderen Backslashes hab ich jetzt mal stillschweigend weginterpretiert. Bis auf das vor dem " waren sie jedoch alle überflüssig. Vor dem " wird ein \ benötigt, damit nicht schon dort das Ende des mit " eingeleiteten Strings erkannt wird.

          Der entstandene String wird nun von Javascript an die Reg-Ex-Maschine weitergereicht und von dieser auch nochmal interpretiert. Sie hat dabei ihre eigenen Regeln, in denen der \ auch wieder als Maskierungszeichen verwendet wird. Ein wörltich gemeinter \ muss als \\ notiert werden. Die Regex-Maschine liest also am Ende [\/:*?"<>|] was eine Zeichenklasse mit ein paar Zeichen darin darstellt.

          replace(/[\\\/:*\?"<>|]/g, '')
          

          Der Kontext hier ist etwas anders, der reguläre Ausdruck ist als Regex-Literal geschrieben und steht als solcher direkt im Code und nicht in einem Javascript-String-Literal wie oben.

          Ein Regex-Literal wird von je einem / eingerahmt. Kommt ein / im Ausdruck selbst vor, muss der maskiert werden. Die ersten beiden \\ ergeben einen wörtlichen , der nächste \ maskiert den Slash /, damit nicht schon dort das Ende des Regex-Literals erkannt wird. Der \ vor dem ? ist wieder überflüssig, weil wir uns in einer Zeichenklasse befinden, eingerahmt durch [ und ]. Außerhalb der Zeichenklasse wäre der \ notwendig, wenn ein literales ? gemeint ist.

          dedlfix.

          1. Hallo dedlfix, herzlichen Dank für deine tolle Erklärung.

            Ich sehe hier einen Stringanfang ". Dann kommt (die Klammer ignorierend) ein , welches dem folgenden Zeichen eine besondere Bedeutung gibt. Das folgende \ heißt in dem Fall, dass genau ein \ wörtlich gemeint ist. Die zwei \\ fallen damit zu einem \ zusammen. Mit den nächsten beiden passiert dasselbe. Der entstehende String ist also letztlich [\\/:*?"<>|]

            Ich will jetzt nicht nerven aber im Fall des Backslash \ ist es mir dennoch nicht ganz klar. Ich habe das String Literal mit einfachem Hochkomma versehen und alle überflüssingen \ entfernt. Damit der Backslash erkannt wird braucht man wirklich 4 \ bzw 3. Nur so kommt die Alert Meldung. Aber ich dachte eigentlich einer müsste doch reichen?

            new RegExp('[\\\\/:*?"<>|]');
            if(!fname.match(rexp))  
              {  
              //alle OK  
              }  
              else  
              {  
              alert('Keine gültige Zeichen sind < > ? " : | \ / *'); 
              }
            
            1. Tach!

              Ich habe das String Literal mit einfachem Hochkomma versehen und alle überflüssingen \ entfernt. Damit der Backslash erkannt wird braucht man wirklich 4 \ bzw 3. Nur so kommt die Alert Meldung. Aber ich dachte eigentlich einer müsste doch reichen?

              Nein, weil der bereits vom String-Literal vereinnahmt wird. Da kommt dann nur noch ein / beim Regex an. Du willst aber / und \ prüfen.

              Vielleicht wird es etwas deutlicher, wenn wir mal den / an eine andere Stelle setzen.

              RegExp('[\\:*?"<>|/]');

              Zwei \\ werden benötigt, um ein einzelnes wörtliches \ in einem String-Literal darzustellen. Der Regexp bekommt daraufhin \: und denkt sich, dass das ein maskierter : ist und weg war der verbliebene \. Deswegen brauchte es doppelt so viele, damit das Stringliteral seinen Teil bekommt und für den Regex noch genügend übrigbleiben.

              new RegExp('[\\\\/:*?"<>|]');
              if(!fname.match(rexp))  
              

              Aus zwei geschachtelten Kontexten mach ich mal nur einen und außerdem ist wieder der / ans Ende gewandert.

              if(!fname.match(/[\\:*?"<>|\/]/))  
              

              Zwei Backslashes braucht es, damit einer wörtlich übrigbleibt und nicht \: als maskiertes : gewertet wird. Den \ vor dem / braucht es, damit der / nicht als Regex-Ende erkannt wird.

              dedlfix.

              1. Hallo dedlfix, nochmals herzlichen Dank für deine Geduld. Auch wegen der Umstellung mit dem / am Ende und deiner Erklärung ist es mir jetzt klarer gewirden. Ich sehe schon: Das Thema Regex ist nicht trivial.

                vielen Dank Gruss Werner

            2. Hallo,

              herzlichen Dank für deine tolle Erklärung.

              ja, ich fand sie auch hervorragend.

              Ich will jetzt nicht nerven aber im Fall des Backslash \ ist es mir dennoch nicht ganz klar. Ich habe das String Literal mit einfachem Hochkomma versehen und alle überflüssingen \ entfernt.

              Das ist okay, so musst du das Anführungszeichen innerhalb des Strings nicht extra maskieren.

              Damit der Backslash erkannt wird braucht man wirklich 4 \ bzw 3. Nur so kommt die Alert Meldung.
              Aber ich dachte eigentlich einer müsste doch reichen?

              Was hast du an der ausführlichen Erklärung von dedlfix nicht verstanden? EIN Backslash ist in einem Javascript-String lediglich eine Art Escape-Zeichen, ein Indikator dafür, dass das (die) darauffolgende(n) Zeichen eine Sonderbedeutung hat/haben. Nur wenn die Kombination aus Backslash und nachfolgendem Zeichen keinen speziellen Sinn ergibt, wird der einzelne Backslash als solcher interpretiert. Das ist aber eigentlich bloß eine Kulanzregelung.

              Du musst aber zwei Backslashes an die Regex-Engine übergeben, damit die ihrerseit erkennt, dass da ein Backslash wörtlich gemeint ist, und nicht als Escape-Sequenz mit dem folgenden Zeichen zusammenfallen soll. Notierst du zwei Backslashes im Javascript-String, fasst der Javascript-Parser die aber schon zu einem zusammen, denn Backslash-Backslash ist die korrekte Escape-Sequenz für einen Backslash, der wörtlich im String vorkommen aoll. Folglich musst du eigentlich vier Stück schreiben - wobei der vierte wegen der oben erwähnten Kulanzregelung entfallen kann.

              Jetzt alle Klarheiten beseitigt?

              So long,
               Martin

              1. Tach!

                Nur wenn die Kombination aus Backslash und nachfolgendem Zeichen keinen speziellen Sinn ergibt, wird der einzelne Backslash als solcher interpretiert. Das ist aber eigentlich bloß eine Kulanzregelung.

                Ja, aber die von PHP. Javascript kennt diese Kulanz nicht. Bei einer Escape-Sequenz, die keine der definierten ist, wird der \ weginterpretiert und das folgende Zeichen bleibt übrig. Bei PHP bleibt auch der \ stehen.

                Folglich musst du eigentlich vier Stück schreiben - wobei der vierte wegen der oben erwähnten Kulanzregelung entfallen kann.

                Nö, dann wirds falsch und der \ verschwindet am Ende ganz.

                dedlfix.

                1. Hallo,

                  Nur wenn die Kombination aus Backslash und nachfolgendem Zeichen keinen speziellen Sinn ergibt, wird der einzelne Backslash als solcher interpretiert. Das ist aber eigentlich bloß eine Kulanzregelung.

                  Ja, aber die von PHP. Javascript kennt diese Kulanz nicht. Bei einer Escape-Sequenz, die keine der definierten ist, wird der \ weginterpretiert und das folgende Zeichen bleibt übrig. Bei PHP bleibt auch der \ stehen.

                  uii, gut dass du es erwähnst. Das war mir nämlich nicht bewusst, und dann ist auch die hier im Thread mehrmals auftauchende Version mit drei Backslashes an dieser Stelle falsch.

                  Folglich musst du eigentlich vier Stück schreiben - wobei der vierte wegen der oben erwähnten Kulanzregelung entfallen kann.

                  Nö, dann wirds falsch und der \ verschwindet am Ende ganz.

                  Gut, dass wir drüber gesprochen haben. ;-)

                  So long,
                   Martin

                  1. Hallo Der Martin,

                    uii, gut dass du es erwähnst. Das war mir nämlich nicht bewusst, und dann ist auch die hier im Thread mehrmals auftauchende Version mit drei Backslashes an dieser Stelle falsch.

                    Ich vermute, dass die Variante mit den drei Backslashes ihre Ursache in Kramdown hat.

                    Bis demnächst
                    Matthias

                    --
                    Signaturen sind bloed (Steel) und Markdown ist mächtig.
                    1. Hallo,

                      uii, gut dass du es erwähnst. Das war mir nämlich nicht bewusst, und dann ist auch die hier im Thread mehrmals auftauchende Version mit drei Backslashes an dieser Stelle falsch.

                      Ich vermute, dass die Variante mit den drei Backslashes ihre Ursache in Kramdown hat.

                      könnte auch sein. Und das wäre dann nochmal Wasser auf Gunnars Mühlen. Auf meine übrigens auch.

                      Ciao,
                       Martin