Coder Perfect

How can I determine whether a string is a legitimate number?


I’m hoping there’s something that’s similar to the old VB6 IsNumeric() function?

Asked by Electrons_Ahoy

Solution #1

2nd October 2020: Many bare-bones techniques are riddled with subtle flaws (e.g. whitespace, implicit partial parsing, radix, array coercion, etc.) that many of the solutions here overlook. The implementation below may work for you, but keep in mind that it does not support number separators other than the decimal point “.”:

function isNumeric(str) {
  if (typeof str != "string") return false // we only process strings!  
  return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...
         !isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail

Regardless of whether the variable’s content is a string or a number, this method works.

isNaN(num)         // returns true if the variable does NOT contain a valid number
isNaN(123)         // false
isNaN('123')       // false
isNaN('1e10000')   // false (This translates to Infinity, which is a number)
isNaN('foo')       // true
isNaN('10px')      // true
isNaN('')          // false
isNaN(' ')         // false
isNaN(false)       // false

You can, of course, nullify this if necessary. To put the IsNumeric example you supplied into practice, for example:

function isNumeric(num){
  return !isNaN(num)

Solely works if the string contains only numeric characters; otherwise, NaN is returned.

+num               // returns the numeric value of the string, or NaN 
                   // if the string isn't purely numeric characters
+'12'              // 12
+'12.'             // 12
+'12..'            // NaN
+'.12'             // 0.12
+'..12'            // NaN
+'foo'             // NaN
+'12px'            // NaN

For example, to translate ’12px’ to 12, use this formula:

parseInt(num)      // extracts a numeric value from the 
                   // start of the string, or NaN.
parseInt('12')     // 12
parseInt('aaa')    // NaN
parseInt('12px')   // 12
parseInt('foo2')   // NaN      These last three may
parseInt('12a5')   // 12       be different from what
parseInt('0x10')   // 16       you expected to see.

Keep in mind that, unlike +num, parseInt will convert a float to an integer by cutting off anything after the decimal point (if you wish to use parseInt() because of this behavior, you should probably use another method instead):

+'12.345'          // 12.345
parseInt(12.345)   // 12
parseInt('12.345') // 12

It may seem counterintuitive to use empty strings. isNaN() assumes the same: +num turns empty strings or strings with spaces to zero.

+''                // 0
+'   '             // 0
isNaN('')          // false
isNaN('   ')       // false

However, parseInt() disagrees:

parseInt('')       // NaN
parseInt('   ')    // NaN

Answered by Dan

Solution #2

Regex is a nice way to go if you merely want to check if a string is a whole integer (no decimal places). Other approaches, such as isNaN, are overly sophisticated for such a simple problem.

function isNumeric(value) {
    return /^-?\d+$/.test(value);

console.log(isNumeric('abcd'));         // false
console.log(isNumeric('123a'));         // false
console.log(isNumeric('1'));            // true
console.log(isNumeric('1234567890'));   // true
console.log(isNumeric('-23'));          // true
console.log(isNumeric(1234));           // true
console.log(isNumeric(1234n));          // true
console.log(isNumeric('123.4'));        // false
console.log(isNumeric(''));             // false
console.log(isNumeric(undefined));      // false
console.log(isNumeric(null));           // false

Use this if you only want to allow positive whole numbers:

function isNumeric(value) {
    return /^\d+$/.test(value);

console.log(isNumeric('123'));          // true
console.log(isNumeric('-23'));          // false

Answered by Gavin

Solution #3

You may also take the RegExp route:

var num = "987238";

  //valid integer (positive or negative)
}else if(num.match(/^\d+\.\d+$/)){
  //valid float
  //not valid number

Answered by roenving

Solution #4

There are several faults in the accepted response to this question (as highlighted by couple of other users). This is one of the simplest and most tested approaches in javascript:

function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);

Some good test cases are listed below:

console.log(isNumeric(12345678912345678912)); // true
console.log(isNumeric('2 '));                 // true
console.log(isNumeric('-32.2 '));             // true
console.log(isNumeric(-32.2));                // true
console.log(isNumeric(undefined));            // false

// the accepted answer fails at these tests:
console.log(isNumeric(''));                   // false
console.log(isNumeric(null));                 // false
console.log(isNumeric([]));                   // false

Answered by Hamzeen Hameem

Solution #5

You can’t use parseInt()/ parseFloat(), Number(), or!isNaN() by themselves to ensure that a string contains only a number, any number (integer or floating point), and exactly a number. Because!isNaN() returns true when Number() returns a number and false when it returns NaN, I’m going to leave it out of the rest of the explanation.

The issue with parseFloat() is that it returns a number if the string contains any number, even if it does not contain solely and exactly a number:

parseFloat("2016-12-31")  // returns 2016
parseFloat("1-1") // return 1
parseFloat("1.2.3") // returns 1.2

The issue with Number() is that it returns a number even if the given value isn’t a number at all!

Number("") // returns 0
Number(" ") // returns 0
Number(" \u00A0   \t\n\r") // returns 0

The problem with rolling your own regex is that unless you create the exact regex for matching a floating point number as Javascript recognizes it you are going to miss cases or recognize cases where you shouldn’t. Why, even if you have the ability to roll your own regex? There are simpler built-in ways to do it.

Number() (and isNaN()) turns out to be the correct answer in every scenario when parseFloat() produces a number when it shouldn’t, and vice versa. So, to see if a string is indeed just a number, call both functions and see if they both return true:

function isNumber(str) {
  if (typeof str != "string") return false // we only process strings!
  // could also coerce to string: str = ""+str
  return !isNaN(str) && !isNaN(parseFloat(str))

Answered by Michael

Post is based on