Der beste Weg zur alphanumerischen Prüfung in Javascript

107

Was ist der beste Weg, um eine alphanumerische Prüfung für ein INPUTFeld in durchzuführen JSP? Ich habe meinen aktuellen Code angehängt

<script type="text/javascript">
  function validateCode(){
      var TCode = document.getElementById('TCode').value;
      for(var i=0; i<TCode.length; i++)
      {
        var char1 = TCode.charAt(i);
        var cc = char1.charCodeAt(0);

        if((cc>47 && cc<58) || (cc>64 && cc<91) || (cc>96 && cc<123))
        {

        }
         else {
         alert('Input is not alphanumeric');
         return false;
         }
      }
     return true;     
   }

t0mcat
quelle
2
Hängt davon ab, wie Sie "am besten" definieren. Die meisten der folgenden Antworten deuten auf einen regulären Ausdruck hin, der viel langsamer als Ihr ursprünglicher Code ist . Ich habe Ihren Code ein wenig aufgeräumt , was tatsächlich sehr gut funktioniert.
Michael Martin-Smucker

Antworten:

100

Sie können diesen regulären Ausdruck verwenden /^[a-z0-9]+$/i

Mahesh Velaga
quelle
4
Dies setzt natürlich voraus, dass die leere Zeichenfolge ( "") nicht übereinstimmt.
zzzzBov
15
ñfällt nicht in das Muster, jedoch voll gültiges UTF-8-Zeichen.
Oybek
8
/ ^ [a-z0-9] + $ / i.test (TCode)
Alex V
3
Das Testen eines regulären Ausdrucks scheint viel langsamer zu sein (66% in Chrome 36) als charCodeAt(). Siehe jsPerf und meine Antwort unten .
Michael Martin-Smucker
5
Diese Regex funktioniert nicht mit Sonderzeichen, die in einigen Sprachen verwendet werden, wie "ą", "ź", "ć" usw.
Rafał Swacha
79

Die ursprüngliche Neigung des Fragestellers zur Verwendung str.charCodeAt(i)scheint schneller zu sein als die Alternative mit regulären Ausdrücken. In meinem Test auf jsPerf ist die RegExp-Option in Chrome 36 66% langsamer (und in Firefox 31 etwas langsamer).

Hier ist eine bereinigte Version des ursprünglichen Validierungscodes, der eine Zeichenfolge empfängt und zurückgibt trueoder false:

function isAlphaNumeric(str) {
  var code, i, len;

  for (i = 0, len = str.length; i < len; i++) {
    code = str.charCodeAt(i);
    if (!(code > 47 && code < 58) && // numeric (0-9)
        !(code > 64 && code < 91) && // upper alpha (A-Z)
        !(code > 96 && code < 123)) { // lower alpha (a-z)
      return false;
    }
  }
  return true;
};

Natürlich kann es auch andere Überlegungen geben, beispielsweise die Lesbarkeit. Ein einzeiliger regulärer Ausdruck ist definitiv schöner anzusehen. Wenn Sie sich jedoch ausschließlich mit Geschwindigkeit befassen, sollten Sie diese Alternative in Betracht ziehen.

Michael Martin-Smucker
quelle
17
Programmierer lieben das Aussehen von Code, aber Sie sehen seine innere Schönheit.
Ziggy
Interessanter alternativer Ansatz - kam mir noch nie in den Sinn. Ich bin nur mit Regex hierher gekommen!
Ozzy432836
Die Antwort, die Sie zum Nachdenken anregt und Sie verstehen lässt, was es "Programmieren" bedeutet. Ich benutze Ihre Denkweise in meiner Antwort
Oscar Zarrus
41

Überprüfen Sie es mit einem regulären Ausdruck.

Javascript-Regexen haben keine POSIX-Zeichenklassen, daher müssen Sie Zeichenbereiche manuell schreiben:

if (!input_string.match(/^[0-9a-z]+$/))
  show_error_or_something()

Hier ^bedeutet Zeichenfolgenanfang und $Zeichenfolgenende und [0-9a-z]+bedeutet ein oder mehrere Zeichen von 0bis 9ODER von abis z.

Weitere Informationen zu Javascript Regexen finden Sie hier: https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions

Mischa Arefiev
quelle
14
+1, um den grundlegenden regulären Ausdruck zu erklären und eine Verknüpfung zu einer Anleitung herzustellen, anstatt dem Benutzer eine "magische Zeichenfolge" zu geben.
Charles Burns
4
@inor können Sie einfach 'i' am Ende der Regex hinzufügen, um die Groß- und Kleinschreibung zu /^[a-z0-9]+$/i
berücksichtigen .ie
33

Sie müssen es nicht einzeln tun. Machen Sie einfach einen Test für alle, die nicht alphanumerisch sind. Wenn einer gefunden wird, schlägt die Validierung fehl.

function validateCode(){
    var TCode = document.getElementById('TCode').value;
    if( /[^a-zA-Z0-9]/.test( TCode ) ) {
       alert('Input is not alphanumeric');
       return false;
    }
    return true;     
 }

Wenn es mindestens eine Übereinstimmung mit einer nicht alphanumerischen Zahl gibt, wird dies der Fall sein return false.

user113716
quelle
6

Ich würde eine String-Prototyp-Methode erstellen:

String.prototype.isAlphaNumeric = function() {
  var regExp = /^[A-Za-z0-9]+$/;
  return (this.match(regExp));
};

Dann wäre die Verwendung:

var TCode = document.getElementById('TCode').value;
return TCode.isAlphaNumeric()
Justin
quelle
2
DJDavid98: Ich glaube nicht, dass hier die Regel "Objekte, die Sie nicht besitzen, nicht ändern" gilt. Justin erweiterte lediglich die Funktionen von String und änderte keine vorhandenen Funktionen. Für die Perspektive in der C # -Welt würde dies als eine vollkommen gültige Verwendung einer Erweiterungsmethode angesehen. Selbst wenn eines Tages "String.isAlphaNumeric (): boolean" von Browserherstellern implementiert würde, würden sich weder die Signatur noch die Aktion tatsächlich ändern, sodass ich in diesem Beispiel keine Einschränkungen der Wartbarkeit feststellen kann. Dass etwas eine Regel ist, bedeutet nicht, dass es keine Ausnahmen gibt.
Risto Välimäki
5
    // On keypress event call the following method
    function AlphaNumCheck(e) {
        var charCode = (e.which) ? e.which : e.keyCode;
        if (charCode == 8) return true;

        var keynum;
        var keychar;
        var charcheck = /[a-zA-Z0-9]/;
        if (window.event) // IE
        {
            keynum = e.keyCode;
        }
        else {
            if (e.which) // Netscape/Firefox/Opera
            {
                keynum = e.which;
            }
            else return true;
        }

        keychar = String.fromCharCode(keynum);
        return charcheck.test(keychar);
    }

Darüber hinaus hilft dieser Artikel auch beim Verständnis der alphanumerischen JavaScript-Validierung.

Neerajan
quelle
3

Entschuldigung, keine Kontroverse. Aber damit die Community so wächst, wie ich in diesen Jahren gewachsen bin, ist es gut, sich Notizen zu machen.

Die echte alphanumerische Zeichenfolge ist wie "0a0a0a0b0c0d"und nicht wie "000000"oder "qwertyuio".

Alle Antworten, die ich hier gelesen habe, sind truein beiden Fällen zurückgekehrt. Und vergib mir, IMHO, das ist nicht richtig .

Wenn ich überprüfen möchte, ob meine "00000"Zeichenfolge alphanum ist, ist meine "menschliche" Antwort zweifellos FALSCH.

Warum? Einfach. Ich kann keinen Buchstaben char finden. Ist also eine einfache numerische Zeichenfolge [0-9].

Wenn ich andererseits meine "abcdefg"Zeichenfolge überprüfen wollte , ist meine "menschliche" Antwort sogar FALSCH. Ich sehe keine Zahlen, daher ist es nicht alphanumerisch. Nur Alpha [a-zA-Z].

Die Antwort von Michael Martin-Smucker war aufschlussreich.

Er strebte jedoch eine bessere Leistung anstelle von Regex an. Dies ist wahr, wenn man einen niedrigen Level verwendet, gibt es eine bessere Leistung. Aber die Ergebnisse sind die gleichen. Die Zeichenfolgen "0123456789"(nur numerisch), "qwertyuiop"(nur Alpha) und "0a1b2c3d4f4g"(alphanumerisch) werden TRUEals alphanumerisch zurückgegeben. Gleicher Regex- /^[a-z0-9]+$/iWeg. Der Grund, warum die Regex nicht funktioniert, ist so einfach wie offensichtlich. Die Syntax []gibt oder , nicht und an . Wenn es also nur numerisch ist oder wenn es nur Buchstaben sind, gibt Regex zurück true.

Aber der Michael Martin-Smucker Antwort wurde dennoch aufschlussreich. Für mich. Es erlaubte mir, auf "niedriger Ebene" zu denken, um eine echte Funktion zu erstellen, die eine alphanumerische Zeichenfolge eindeutig verarbeitet. Ich nannte es wie PHP relative Funktion ctype_alnum( edit 2020-02-18: Wobei dies jedoch OR und nicht AND prüft ).

Hier ist der Code:

function ctype_alnum(str) {
  var code, i, len;
    var isNumeric = false, isAlpha = false; //I assume that it is all non-alphanumeric



  for (i = 0, len = str.length; i < len; i++) {
    code = str.charCodeAt(i);


        switch (true){
            case code > 47 && code < 58: // check if 0-9
                isNumeric = true;
                break;
            case (code > 64 && code < 91) || (code > 96 && code < 123): //check if A-Z or a-z
                isAlpha = true;
                break;
            default: // not 0-9, not A-Z or a-z
                return false; //stop function with false result, no more checks

        }

  }

  return isNumeric && isAlpha; //return the loop results, if both are true, the string is certainly alphanumeric
};

... und hier ist die DEMO

Ich bin zu dieser Diskussion gekommen, weil ich nach einer Alternative in Javascript zur PHP-Funktion gesucht habe. Ich habe die Antwort "Ready-to-Go" nicht gefunden, aber wie so oft bei Stackoverflow ist das Konzept des Wissens und des Vergleichs untereinander etwas Erhabenes, das Sie dazu bringt, über die Antwort von jemandem nachzudenken und gemeinsam die Lösung zu finden, die Sie waren suchen, aber Sie dachten nicht, dass Sie es wussten.

Und teile es!

Beste

Oscar

Oscar Zarrus
quelle
Das obige löst alphaAndNumeric, nicht alphaNumeric. return isNumeric || isAlpha;ist alphaNumeric. Das Obige kann für einige hilfreich sein.
TamusJRoyce
1
@ TamusJRoyce natürlich. Aber Bild, um eine Umsatzsteuer-Identifikationsnummer zu überprüfen, wobei in einigen Fällen nur numerisch und in anderen Fällen alphanumerisch sein muss. Übrigens merke ich erst jetzt, meine Schuld, dass die relative PHP-Funktion ODER anstelle von UND vorsieht. Das ist ein Problem, weil ich alle Codes meiner PHP-Anwendungen ändern musste, um eine Ad-hoc-Funktion zu erstellen, die den AND
Oscar Zarrus
3

In einer engen Schleife ist es wahrscheinlich besser, Regex zu vermeiden und Ihre Zeichen fest zu codieren:

const CHARS = new Set("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
function isAlphanumeric(char) {
    return CHARS.has(char);
}
Malganis
quelle
können Sie dies erklären
fauler Entwickler
2
Dieser Code ist O (N ^ 2), wenn eine ganze Zeichenfolge in einer Schleife gescannt wird, und führt zu einer weitaus schlechteren Leistung als selbst die schlechtesten vorgestellten Regex-Lösungen (z. B. wenn ein Benutzer alle Zs übergibt, muss der indexOf () an die scannen Ende für jedes Zeichen). Dies verursacht nicht nur möglicherweise den Overhead beim Scannen der gesamten 0-Z-Zeichenfolge (durchschnittlich 18 Zeichenvergleiche pro Aufruf), sondern auch zwei Funktionsaufrufe im Wert von Overhead pro Zeichen der Quellzeichenfolge - ein ziemlich signifikanter konstanter Zeitwert! Der Code kann sogar eine DoS-Sicherheitsanfälligkeit verursachen, je nachdem, wo er verwendet wird.
CubicleSoft
1
Sie haben absolut Recht, CubicleSoft. Ich habe die Antwort aktualisiert, um JS Set zu verwenden.
Malganis
0

Um zu überprüfen, ob input_string alphanumerisch ist, verwenden Sie einfach:

input_string.match(/[^\w]|_/) == null
Mark Baaijens
quelle