Meilleur moyen de vérifier alphanumérique en Javascript

107

Quelle est la meilleure façon d'effectuer une vérification alphanumérique sur un INPUTchamp dans JSP? J'ai joint mon code actuel

<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
la source
2
Cela dépend de la façon dont vous définissez le «meilleur». La plupart des réponses ci-dessous suggèrent regex, qui fonctionne beaucoup plus lentement que votre code d'origine . J'ai nettoyé un peu votre code , qui fonctionne très bien.
Michael Martin-Smucker

Réponses:

100

Vous pouvez utiliser cette regex /^[a-z0-9]+$/i

Mahesh Velaga
la source
4
bien sûr, cela suppose que la chaîne vide ( "") ne doit pas correspondre.
zzzzBov
15
ñne tombe pas dans le modèle, cependant le caractère UTF-8 entièrement valide.
Oybek le
8
/ ^ [a-z0-9] + $ / i.test (TCode)
Alex V
3
Tester une expression régulière semble être beaucoup plus lent (66% dans Chrome 36) que charCodeAt(). Voir jsPerf et ma réponse ci-dessous .
Michael Martin-Smucker
5
Cette expression régulière ne fonctionne pas avec les caractères spéciaux utilisés dans certaines langues, comme "ą", "ź", "ć", etc.
Rafał Swacha
79

L'inclination initiale du demandeur à utiliser str.charCodeAt(i)semble être plus rapide que l'alternative à l'expression régulière. Dans mon test sur jsPerf, l'option RegExp est 66% plus lente dans Chrome 36 (et légèrement plus lente dans Firefox 31).

Voici une version nettoyée du code de validation d'origine qui reçoit une chaîne et renvoie trueou 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;
};

Bien sûr, il peut y avoir d'autres considérations, telles que la lisibilité. Une expression régulière sur une ligne est certainement plus jolie à regarder. Mais si vous êtes strictement préoccupé par la vitesse, vous voudrez peut-être envisager cette alternative.

Michael Martin-Smucker
la source
17
Les programmeurs adorent l'apparence du code, mais vous voyez sa beauté intérieure.
Ziggy
Approche alternative intéressante - ne m'a même jamais traversé l'esprit. Je suis venu ici avec seulement regex en tête!
ozzy432836
La réponse qui vous fait réfléchir et vous fait comprendre ce que signifie «programmation». J'utilise votre façon de penser, dans ma réponse
Oscar Zarrus
42

Vérifiez-le avec une regex.

Javascript regexen n'a pas de classes de caractères POSIX, vous devez donc écrire manuellement des plages de caractères:

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

Ici ^signifie début de chaîne et $fin de chaîne, et [0-9a-z]+signifie un ou plusieurs caractères de 0à 9OU de aà z.

Plus d'informations sur Javascript regexen ici: https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions

Mischa Arefiev
la source
14
+1 pour expliquer les expressions régulières de base et créer un lien vers un guide, plutôt que de donner à l'utilisateur une "chaîne magique".
Charles Burns
4
@inor, vous pouvez simplement ajouter 'i' à la fin de l'expression régulière pour spécifier l'insensibilité à la casse, .ie /^[a-z0-9]+$/iet cela couvrira les lettres minuscules et majuscules
LJH
33

Vous n'avez pas besoin de le faire un à la fois. Faites simplement un test pour ceux qui ne sont pas alphanumériques. S'il en trouve un, la validation échoue.

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

S'il y a au moins une correspondance d'un non alphanumérique, il le sera return false.

utilisateur113716
la source
6

Je créerais une méthode prototype String:

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

Ensuite, l'utilisation serait:

var TCode = document.getElementById('TCode').value;
return TCode.isAlphaNumeric()
Justin
la source
2
DJDavid98: Je ne pense pas que la règle "ne modifiez pas les objets que vous ne possédez pas" s'applique ici. Justin étendait simplement les capacités de String, ne modifiait pas les fonctionnalités existantes. Pour la perspective, dans le monde C #, cela serait considéré comme une utilisation parfaitement valide d'une méthode d'extension. Même si un jour "String.isAlphaNumeric (): boolean" serait implémenté par les fabricants de navigateurs, ni la signature ni l'action ne changeraient réellement, donc je ne vois aucune réduction de maintenabilité dans cet exemple particulier. Ce quelque chose est une règle n'implique pas qu'il n'y a pas d'exceptions.
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);
    }

En outre, cet article aide également à comprendre la validation alphanumérique JavaScript.

Neerajan
la source
4

Excusez-moi à tous, pas de controverse. Mais pour que la communauté grandisse comme elle m'a fait grandir ces dernières années, il est bon de prendre quelques notes.

La vraie chaîne alphanumérique est comme "0a0a0a0b0c0d"et pas comme "000000"ou "qwertyuio".

Toutes les réponses que j'ai lues ici, sont retournées truedans les deux cas. Et pardonnez-moi, à mon humble avis, ce n'est pas juste .

Si je veux vérifier si ma "00000"chaîne est alphanum, ma réponse "humaine" est incontestablement FAUX.

Pourquoi? Facile. Je ne trouve aucune lettre char. Donc, est une simple chaîne numérique [0-9].

Par contre, si je voulais vérifier ma "abcdefg"chaîne, ma réponse "humaine" est même FAUX. Je ne vois pas de chiffres, donc ce n'est pas alphanumérique. Juste alpha [a-zA-Z].

La réponse de Michael Martin-Smucker a été éclairante.

Cependant, il visait à obtenir de meilleures performances au lieu de regex. C'est vrai, en utilisant un moyen de bas niveau, il y a une meilleure performance. Mais les résultats sont les mêmes. Les chaînes "0123456789"(uniquement numérique), "qwertyuiop"(uniquement alpha) et "0a1b2c3d4f4g"(alphanumérique) sont renvoyées TRUEsous forme alphanumérique. Même /^[a-z0-9]+$/imanière de regex . La raison pour laquelle l'expression régulière ne fonctionne pas est aussi simple qu'évidente. La syntaxe []indique ou , non et . Donc, si c'est uniquement numérique ou si ce n'est que des lettres, regex retourne true.

Mais la réponse de Michael Martin-Smucker était néanmoins éclairante. Pour moi. Cela m'a permis de penser à "bas niveau", de créer une vraie fonction qui traite sans ambiguïté une chaîne alphanumérique. Je l'ai appelé comme fonction relative PHP ctype_alnum( modifier 2020-02-18: Où, cependant, cela vérifie OU et non ET ).

Voici le 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
};

... et voici la DEMO

Je suis venu à cette discussion parce que je cherchais une alternative en javascript à la fonction PHP. Je n'ai pas trouvé la réponse «prête à l'emploi», mais comme cela arrive souvent sur Stackoverflow, le concept de connaissance et de comparaison les uns avec les autres est quelque chose de sublime, qui vous amène à réfléchir à la réponse de quelqu'un et à trouver ensemble la solution que vous étiez chercher, mais vous ne pensiez pas que vous le saviez.

Et partagez-le!

Meilleur

oscar

Oscar Zarrus
la source
Ce qui précède résout alphaAndNumeric, pas alphaNumeric. return isNumeric || isAlpha;est alphaNumeric. Ce qui précède peut être utile à certains.
TamusJRoyce
1
@TamusJRoyce bien sûr. Mais l'image pour vérifier un numéro de TVA où dans certains cas est juste numérique et dans d'autres cas doit être alphanumérique. Au fait, je me rends compte seulement maintenant, ma faute, que la fonction PHP relative prévoit OU au lieu de AND. Ce qui est un problème car j'ai dû modifier tous les codes de mes applications PHP, en créant une fonction ad-hoc qui prévoyait l'AND
Oscar Zarrus
3

Dans une boucle serrée, il est probablement préférable d'éviter les regex et de coder en dur vos caractères:

const CHARS = new Set("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
function isAlphanumeric(char) {
    return CHARS.has(char);
}
Malganis
la source
pouvez-vous expliquer cela
lazydeveloper
2
Ce code est O (N ^ 2) lors de l'analyse d'une chaîne entière dans une boucle et entraînera des performances bien pires que même les pires solutions regex présentées (par exemple, un utilisateur passe tous les 'Z', l'indexOf () doit scanner vers le fin pour chaque caractère). Non seulement cela entraîne-t-il potentiellement la surcharge de l'analyse de toute la chaîne 0-Z (en effectuant, en moyenne, des comparaisons de 18 caractères par appel), mais également deux appels de fonction d'une valeur de surcharge par caractère de la chaîne source - une valeur de temps constante assez importante! Le code pourrait même introduire une vulnérabilité DoS selon l'endroit où il est utilisé.
CubicleSoft le
1
Vous avez absolument raison CubicleSoft. J'ai mis à jour la réponse pour utiliser JS Set.
Malganis le
0

Pour vérifier si input_string est alphanumérique, utilisez simplement:

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