187

What is the best way to perform an alphanumeric check on an INPUT field in JSP? I have attached my current code

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

Parzh from Ukraine
  • 7,999
  • 3
  • 34
  • 65
t0mcat
  • 5,511
  • 19
  • 45
  • 58
  • 4
    Depends how you define "best". Most of the answers below suggest regex, which performs [much slower than your original code](http://jsperf.com/alphanumeric-charcode-vs-regexp). I've [cleaned up your code](http://stackoverflow.com/a/25352300/388639) a bit, which actually performs very well. – Michael Martin-Smucker Aug 17 '14 at 18:31

15 Answers15

153

The asker's original inclination to use str.charCodeAt(i) appears to be faster than the regular expression alternative. In my test on jsPerf the RegExp option performs 66% slower in Chrome 36 (and slightly slower in Firefox 31).

Here's a cleaned-up version of the original validation code that receives a string and returns true or 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;
};

Of course, there may be other considerations, such as readability. A one-line regular expression is definitely prettier to look at. But if you're strictly concerned with speed, you may want to consider this alternative.

Michael Martin-Smucker
  • 11,927
  • 7
  • 31
  • 36
  • 27
    Programmers love the look of code, but you see its inner beauty. – Ziggy Sep 16 '14 at 03:14
  • Interesting alternative approach - never even crossed my mind. I came here with only regex in mind! – Andy Oct 10 '18 at 13:01
  • The answer that makes you think and makes you understand what it means "programming". I use your way of thinking, in [my answer](https://stackoverflow.com/questions/4434076/best-way-to-alphanumeric-check-in-javascript/53384852#53384852) – Oscar Zarrus Nov 20 '18 at 01:16
  • 6
    Why do we need to do comparison in charCode `charCodeAt`? Can't we just perform string comparison with the string char `(c >= '0' && c <= '9')`, `(c >= 'a' && c <= 'z')`, `(c >= 'A' && c <= 'Z')`? – Xitang Aug 28 '21 at 05:55
  • I like your way of thinking, performance is very important – mohamed chadad Jun 23 '22 at 21:17
143

You can use this regex /^[a-z0-9]+$/i

Community
  • 1
  • 1
Mahesh Velaga
  • 21,633
  • 5
  • 37
  • 59
  • 5
    of course this assumes that that the empty string (`""`) should not be matched. – zzzzBov Dec 13 '10 at 22:28
  • 25
    `ñ` does not fall into the pattern however fully valid UTF-8 char. – Oybek Apr 04 '13 at 16:35
  • 16
    /^[a-z0-9]+$/i.test( TCode ) – Alex V Oct 14 '13 at 18:12
  • 1
    Or just /^[\w\d]+/.test() – Extaze Jan 11 '14 at 11:36
  • 4
    Testing a regular expression seems to be much slower (66% in Chrome 36) than `charCodeAt()`. See [jsPerf](http://jsperf.com/alphanumeric-charcode-vs-regexp) and [my answer below](http://stackoverflow.com/a/25352300/388639). – Michael Martin-Smucker Aug 17 '14 at 18:29
  • 11
    This regex does not work with special character letters used in some languages, like "ą", "ź", "ć" etc. – Rafał Swacha Jan 15 '16 at 12:01
  • 1
    a little note about this answer. Despite this solution works, this not identify an alphanumeric string because a string `"00"` and a string `"a0"` return `true` in both cases, as a consequence of the regexp `[]` sign means **OR** and not **AND**. The string `"00"` must returns `false` because is not an aphanumeric string, but a couple of zeroes. IMHO – Oscar Zarrus Nov 19 '18 at 23:09
  • 1
    Works, but there's no way I'm using Regex in anything untrusted-client-facing on a server. Too many gotchas. Michael's answer is better if you care about that. – sudo Apr 11 '19 at 05:23
  • 1
    This does the job, but it is less efficient. – Anthony Jun 14 '19 at 17:54
  • 2
    How is this ranked so high ? – Mike Q Apr 18 '20 at 17:23
  • 1
    This only returns true with just letters or just numbers. I thought the aim was the validate inputs with both letters and numbers? – xplorer1 Nov 18 '20 at 10:10
  • 1
    why these things never happen to me ? 1160 score points plus the bounty for a ridiculously simple regex :/ – Nelson Teixeira Mar 25 '21 at 21:01
78

Check it with a regex.

Javascript regexen don't have POSIX character classes, so you have to write character ranges manually:

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

Here ^ means beginning of string and $ means end of string, and [0-9a-z]+ means one or more of character from 0 to 9 OR from a to z.

More information on Javascript regexen here: https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions

Mischa Arefiev
  • 5,227
  • 4
  • 26
  • 34
  • 24
    +1 for explaining the basic regex and linking to a guide, rather than giving the user a "magic string". – Charles Burns Apr 29 '13 at 16:46
  • 4
    @inor you can just add 'i' at the end of the regex to specify case insensitivity, .i.e. `/^[a-z0-9]+$/i` and this will cover both lower and upper case letters – LJH Jul 26 '18 at 17:50
40

You don't need to do it one at a time. Just do a test for any that are not alpha-numeric. If one is found, the validation fails.

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

If there's at least one match of a non alpha numeric, it will return false.

user113716
  • 318,772
  • 63
  • 451
  • 440
31

To match all Unicode letters and numbers you can use a Unicode regex:

const alphanumeric = /^[\p{L}\p{N}]*$/u;

const valid   = "Jòhn꠵Çoe日本語3rd"; // <- these are all letters and numbers
const invalid = "JohnDoe3rd!";

console.log(valid.match(alphanumeric));
console.log(invalid.match(alphanumeric));

In the above regex the u flag enables Unicode mode. \p{L} is short for \p{Letter} and \p{N} is short for \p{Number}. The square brackets [] surrounding them is a normal character class, meaning that a character must be either a letter or a number (in this context). The * is "zero or more", you can change this into + (one or more) if you don't want to allow empty strings .^/$ matches the start/end of the string.


The above will suffice most cases, but might match more than you want. You might not want to match Latin, Arabic, Cyrillic, etc. You might only want to match Latin letters and decimal numbers.

const alphanumeric = /^[\p{sc=Latn}\p{Nd}]*$/u;

const valid   = "JòhnÇoe3rd";
const invalid = "Jòhn꠵Çoe日本語3rd";

console.log(valid.match(alphanumeric));
console.log(invalid.match(alphanumeric));

\p{sc=Latn} is short for \p{Script=Latin}. \p{Nd} is short for \p{Decimal_Number} and matches decimals. The difference with \d is that \p{Nd} does not only match 5, but also , and possibly more.

Checkout the regex Unicode documentation for details, available \p options are linked on the documentation page.

Note that the u flag is not supported by Internet Explorer.

3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
9

I would create a String prototype method:

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

Then, the usage would be:

var TCode = document.getElementById('TCode').value;
return TCode.isAlphaNumeric()
Justin
  • 1,310
  • 3
  • 18
  • 29
  • 8
    [Maintainable JavaScript: Don’t modify objects you don’t own](http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/) – SeinopSys Apr 28 '15 at 09:54
  • 3
    DJDavid98: I don't think that the rule "don't modify objects you don't own" applies here. Justin was just extending the capabilities of String, not modifying existing functionalities. For perspective, in C# world, that would be considered as a perfectly valid usage of an extension method. Even if some day "String.isAlphaNumeric(): boolean" would be implemented by browser manufacturers, neither the signature nor action would actualy change, so I can't see any reductions of maintainability in this particular example. That something is a rule doesn't imply that there are no exceptions. – Risto Välimäki Jun 08 '15 at 06:38
8

Here are some notes: The real alphanumeric string is like "0a0a0a0b0c0d" and not like "000000" or "qwertyuio".

All the answers I read here, returned true in both cases. This is not right.

If I want to check if my "00000" string is alphanumeric, my intuition is unquestionably FALSE.

Why? Simple. I cannot find any letter char. So, is a simple numeric string [0-9].

On the other hand, if I wanted to check my "abcdefg" string, my intuition is still FALSE. I don't see numbers, so it's not alphanumeric. Just alpha [a-zA-Z].

The Michael Martin-Smucker's answer has been illuminating.

However he was aimed at achieving better performance instead of regex. This is true, using a low level way there's a better perfomance. But results it's the same. The strings "0123456789" (only numeric), "qwertyuiop" (only alpha) and "0a1b2c3d4f4g" (alphanumeric) returns TRUE as alphanumeric. Same regex /^[a-z0-9]+$/i way. The reason why the regex does not work is as simple as obvious. The syntax [] indicates or, not and. So, if is it only numeric or if is it only letters, regex returns true.

But, the Michael Martin-Smucker's answer was nevertheless illuminating. For me. It allowed me to think at "low level", to create a real function that unambiguously processes an alphanumeric string. I called it like PHP relative function ctype_alnum (edit 2020-02-18: Where, however, this checks OR and not AND).

Here's the 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
}

And here is a demo:

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

    
loop1:
  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
};

$("#input").on("keyup", function(){

if ($(this).val().length === 0) {$("#results").html(""); return false};
var isAlphaNumeric = ctype_alnum ($(this).val());
    $("#results").html(
        (isAlphaNumeric) ? 'Yes' : 'No'
        )
        
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="input">

<div> is Alphanumeric? 
<span id="results"></span>
</div>

This is an implementation of Michael Martin-Smucker's method in JavaScript.

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
Oscar Zarrus
  • 790
  • 1
  • 9
  • 17
  • 2
    The above solves alphaAndNumeric, not alphaNumeric. `return isNumeric || isAlpha;` is alphaNumeric. The above may be helpful to some. – TamusJRoyce Aug 19 '19 at 15:13
  • 1
    @TamusJRoyce of course. But image to check some VAT number where in some case is just numeric and in other case must be alpha&numeric. By the way, I realize only now, my fault, that the relative PHP function foresees OR instead of AND. Which is a problem because I had to modify all the codes of my PHP applications, creating an ad-hoc function that provided for the AND – Oscar Zarrus Feb 18 '20 at 10:28
  • I feel that a trully alpha&numeric string should be balanced, with 50% of the characters being alpha and the other half being numeric. "qw3rtyuio" can hardly be considered numeric with only a single numeric digit. – AnnanFay Jul 14 '23 at 17:07
8

In a tight loop, it's probably better to avoid regex and hardcode your characters:

const CHARS = new Set("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
function isAlphanumeric(char) {
    return CHARS.has(char);
}
Malganis
  • 338
  • 3
  • 5
  • can you explain this – lazydeveloper Oct 03 '19 at 10:52
  • 2
    This code is O(N^2) when scanning a whole string in a loop and will result in far worse performance than even the worst regex solutions presented (e.g. a user passes in all 'Z's, the indexOf() has to scan to the end for each character). Not only does it potentially incur the overhead of scanning the entire 0-Z string (performing, on average, 18 character comparisons per call) but also two function calls worth of overhead per character of the source string - a rather significant constant time value! The code could even introduce a DoS vulnerability depending on where it is used. – CubicleSoft Apr 19 '20 at 23:45
  • 1
    You are absolutely right CubicleSoft. I updated the answer to use JS Set. – Malganis Apr 21 '20 at 01:50
  • @CubicleSoft I thought the complexity of a set is typical to hashmaps, which as I read is O(1). Do you know any sources which confirm O(N^2) complexity of this algorithm? – jakubiszon Feb 02 '21 at 22:08
  • @jakubiszon The answer was updated by the poster from the original answer. See the edits. Original answer was using indexOf() on a string. – CubicleSoft Feb 03 '21 at 12:36
  • How does this answer (now that it's been edited) compare to Michael Martin-Smucker's answer in terms of performance? – OOPS Studio Mar 21 '23 at 22:14
7
    // 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);
    }

Further, this article also helps to understand JavaScript alphanumeric validation.

Oybek
  • 7,016
  • 5
  • 29
  • 49
Neerajan
  • 239
  • 1
  • 3
  • 12
4

To check whether input_string is alphanumeric, simply use:

input_string.match(/[^\w]|_/) == null
Mark Baaijens
  • 496
  • 5
  • 6
3

If you want a simplest one-liner solution, then go for the accepted answer that uses regex.

However, if you want a faster solution then here's a function you can have.

console.log(isAlphaNumeric('a')); // true
console.log(isAlphaNumericString('HelloWorld96')); // true
console.log(isAlphaNumericString('Hello World!')); // false

/**
 * Function to check if a character is alpha-numeric.
 *
 * @param {string} c
 * @return {boolean}
 */
function isAlphaNumeric(c) {
  const CHAR_CODE_A = 65;
  const CHAR_CODE_Z = 90;
  const CHAR_CODE_AS = 97;
  const CHAR_CODE_ZS = 122;
  const CHAR_CODE_0 = 48;
  const CHAR_CODE_9 = 57;

  let code = c.charCodeAt(0);

  if (
    (code >= CHAR_CODE_A && code <= CHAR_CODE_Z) ||
    (code >= CHAR_CODE_AS && code <= CHAR_CODE_ZS) ||
    (code >= CHAR_CODE_0 && code <= CHAR_CODE_9)
  ) {
    return true;
  }

  return false;
}

/**
 * Function to check if a string is fully alpha-numeric.
 *
 * @param {string} s
 * @returns {boolean}
 */
function isAlphaNumericString(s) {
  for (let i = 0; i < s.length; i++) {
    if (!isAlphaNumeric(s[i])) {
      return false;
    }
  }

  return true;
}
kabirbaidhya
  • 3,264
  • 3
  • 34
  • 59
2
(/[^0-9a-zA-Z]/.test( "abcdeFGh123456" ));
L3xpert
  • 1,109
  • 1
  • 10
  • 19
2
const isAlphaNumeric = (str) => {

  let n1 = false,
    n2 = false;
  const myBigBrainString =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  const myHackyNumbers = "0123456789";

  for (let i = 0; i < str.length; i++) {
    if (myBigBrainString.indexOf(str.charAt(i)) >= 0) {
      n1 = true;
    }
    if (myHackyNumbers.indexOf(str.charAt(i)) >= 0) {
      n2 = true;
    }

    if (n1 && n2) {
      return true;
    }
  }

  return n1 && n2;
};

Works till eternity..

Ali
  • 289
  • 4
  • 10
1

Removed NOT operation in alpha-numeric validation. Moved variables to block level scope. Some comments here and there. Derived from the best Micheal

function isAlphaNumeric ( str ) {

  /* Iterating character by character to get ASCII code for each character */
  for ( let i = 0, len = str.length, code = 0; i < len; ++i ) {

    /* Collecting charCode from i index value in a string */
    code = str.charCodeAt( i ); 

    /* Validating charCode falls into anyone category */
    if (
        ( code > 47 && code < 58) // numeric (0-9)
        || ( code > 64 && code < 91) // upper alpha (A-Z)
        || ( code > 96 && code < 123 ) // lower alpha (a-z)
    ) {
      continue;
    } 

    /* If nothing satisfies then returning false */
    return false
  }

  /* After validating all the characters and we returning success message*/
  return true;
};

console.log(isAlphaNumeric("oye"));
console.log(isAlphaNumeric("oye123"));
console.log(isAlphaNumeric("oye%123"));
Yogi
  • 1,527
  • 15
  • 21
0

Convert string to alphanumeric (Usefull in case of files names)

function stringToAlphanumeric(str = ``) {
  return str
    .split('')
    .map((e) => (/^[a-z0-9]+$/i.test(e) ? e : '_'))
    .join('')
}

const fileName = stringToAlphanumeric(`correct-('"é'è-///*$##~~*\\\"filename`)
console.log(fileName)
// expected  output "correct_filename"
anesboz
  • 412
  • 4
  • 10