Regex for number field [duplicate] - javascript
What's the cleanest, most effective way to validate decimal numbers in JavaScript?
Bonus points for:
Clarity. Solution should be clean and simple.
Cross-platform.
Test cases:
01. IsNumeric('-1') => true
02. IsNumeric('-1.5') => true
03. IsNumeric('0') => true
04. IsNumeric('0.42') => true
05. IsNumeric('.42') => true
06. IsNumeric('99,999') => false
07. IsNumeric('0x89f') => false
08. IsNumeric('#abcdef') => false
09. IsNumeric('1.2.3') => false
10. IsNumeric('') => false
11. IsNumeric('blah') => false
#Joel's answer is pretty close, but it will fail in the following cases:
// Whitespace strings:
IsNumeric(' ') == true;
IsNumeric('\t\t') == true;
IsNumeric('\n\r') == true;
// Number literals:
IsNumeric(-1) == false;
IsNumeric(0) == false;
IsNumeric(1.1) == false;
IsNumeric(8e5) == false;
Some time ago I had to implement an IsNumeric function, to find out if a variable contained a numeric value, regardless of its type, it could be a String containing a numeric value (I had to consider also exponential notation, etc.), a Number object, virtually anything could be passed to that function, I couldn't make any type assumptions, taking care of type coercion (eg. +true == 1; but true shouldn't be considered as "numeric").
I think is worth sharing this set of +30 unit tests made to numerous function implementations, and also share the one that passes all my tests:
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
P.S. isNaN & isFinite have a confusing behavior due to forced conversion to number. In ES6, Number.isNaN & Number.isFinite would fix these issues. Keep that in mind when using them.
Update :
Here's how jQuery does it now (2.2-stable):
isNumeric: function(obj) {
var realStringObj = obj && obj.toString();
return !jQuery.isArray(obj) && (realStringObj - parseFloat(realStringObj) + 1) >= 0;
}
Update :
Angular 4.3:
export function isNumeric(value: any): boolean {
return !isNaN(value - parseFloat(value));
}
Arrrgh! Don't listen to the regular expression answers. RegEx is icky for this, and I'm not talking just performance. It's so easy to make subtle, impossible to spot mistakes with your regular expression.
If you can't use isNaN(), this should work much better:
function IsNumeric(input)
{
return (input - 0) == input && (''+input).trim().length > 0;
}
Here's how it works:
The (input - 0) expression forces JavaScript to do type coercion on your input value; it must first be interpreted as a number for the subtraction operation. If that conversion to a number fails, the expression will result in NaN. This numeric result is then compared to the original value you passed in. Since the left hand side is now numeric, type coercion is again used. Now that the input from both sides was coerced to the same type from the same original value, you would think they should always be the same (always true). However, there's a special rule that says NaN is never equal to NaN, and so a value that can't be converted to a number (and only values that cannot be converted to numbers) will result in false.
The check on the length is for a special case involving empty strings. Also note that it falls down on your 0x89f test, but that's because in many environments that's an okay way to define a number literal. If you want to catch that specific scenario you could add an additional check. Even better, if that's your reason for not using isNaN() then just wrap your own function around isNaN() that can also do the additional check.
In summary, if you want to know if a value can be converted to a number, actually try to convert it to a number.
I went back and did some research for why a whitespace string did not have the expected output, and I think I get it now: an empty string is coerced to 0 rather than NaN. Simply trimming the string before the length check will handle this case.
Running the unit tests against the new code and it only fails on the infinity and boolean literals, and the only time that should be a problem is if you're generating code (really, who would type in a literal and check if it's numeric? You should know), and that would be some strange code to generate.
But, again, the only reason ever to use this is if for some reason you have to avoid isNaN().
This way seems to work well:
function IsNumeric(input){
var RE = /^-{0,1}\d*\.{0,1}\d+$/;
return (RE.test(input));
}
In one line:
const IsNumeric = (num) => /^-{0,1}\d*\.{0,1}\d+$/.test(num);
And to test it:
const IsNumeric = (num) => /^-{0,1}\d*\.{0,1}\d+$/.test(num);
function TestIsNumeric(){
var results = ''
results += (IsNumeric('-1')?"Pass":"Fail") + ": IsNumeric('-1') => true\n";
results += (IsNumeric('-1.5')?"Pass":"Fail") + ": IsNumeric('-1.5') => true\n";
results += (IsNumeric('0')?"Pass":"Fail") + ": IsNumeric('0') => true\n";
results += (IsNumeric('0.42')?"Pass":"Fail") + ": IsNumeric('0.42') => true\n";
results += (IsNumeric('.42')?"Pass":"Fail") + ": IsNumeric('.42') => true\n";
results += (!IsNumeric('99,999')?"Pass":"Fail") + ": IsNumeric('99,999') => false\n";
results += (!IsNumeric('0x89f')?"Pass":"Fail") + ": IsNumeric('0x89f') => false\n";
results += (!IsNumeric('#abcdef')?"Pass":"Fail") + ": IsNumeric('#abcdef') => false\n";
results += (!IsNumeric('1.2.3')?"Pass":"Fail") + ": IsNumeric('1.2.3') => false\n";
results += (!IsNumeric('')?"Pass":"Fail") + ": IsNumeric('') => false\n";
results += (!IsNumeric('blah')?"Pass":"Fail") + ": IsNumeric('blah') => false\n";
return results;
}
console.log(TestIsNumeric());
.as-console-wrapper { max-height: 100% !important; top: 0; }
I borrowed that regex from http://www.codetoad.com/javascript/isnumeric.asp. Explanation:
/^ match beginning of string
-{0,1} optional negative sign
\d* optional digits
\.{0,1} optional decimal point
\d+ at least one digit
$/ match end of string
Yahoo! UI uses this:
isNumber: function(o) {
return typeof o === 'number' && isFinite(o);
}
The accepted answer failed your test #7 and I guess it's because you changed your mind. So this is a response to the accepted answer, with which I had issues.
During some projects, I have needed to validate some data and be as certain as possible that it is a javascript numerical value that can be used in mathematical operations.
jQuery and some other javascript libraries already include such a function, usually called isNumeric. There is also a post on stackoverflow that has been widely accepted as the answer, the same general routine that the aforementioned libraries are using.
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
First, the code above would return true if the argument was an array of length 1, and that single element was of a type deemed as numeric by the above logic. In my opinion, if it's an array then its not numeric.
To alleviate this problem, I added a check to discount arrays from the logic
function isNumber(n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n);
}
Of course, you could also use Array.isArray, jquery $.isArray or prototype Object.isArray instead of Object.prototype.toString.call(n) !== '[object Array]'
My second issue was that Negative Hexadecimal integer literal strings ("-0xA" -> -10) were not being counted as numeric. However, Positive Hexadecimal integer literal strings ("0xA" -> 10) were treated as numeric.
I needed both to be valid numeric.
I then modified the logic to take this into account.
function isNumber(n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}
If you are worried about the creation of the regex each time the function is called then you could rewrite it within a closure, something like this
var isNumber = (function () {
var rx = /^-/;
return function (n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(rx, ''));
};
}());
I then took CMSs +30 test cases and cloned the testing on jsfiddle and added my extra test cases and my above-described solution.
It may not replace the widely accepted/used answer but if this is more of what you are expecting as results from your isNumeric function then hopefully this will be of some help.
EDIT: As pointed out by Bergi, there are other possible objects that could be considered numeric and it would be better to whitelist than a blacklist. With this in mind, I would add to the criteria.
I want my isNumeric function to consider only Numbers or Strings
With this in mind, it would be better to use
function isNumber(n) {
return (Object.prototype.toString.call(n) === '[object Number]' || Object.prototype.toString.call(n) === '[object String]') &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}
Test the solutions
var testHelper = function() {
var testSuite = function() {
test("Integer Literals", function() {
ok(isNumber("-10"), "Negative integer string");
ok(isNumber("0"), "Zero string");
ok(isNumber("5"), "Positive integer string");
ok(isNumber(-16), "Negative integer number");
ok(isNumber(0), "Zero integer number");
ok(isNumber(32), "Positive integer number");
ok(isNumber("040"), "Octal integer literal string");
ok(isNumber(0144), "Octal integer literal");
ok(isNumber("-040"), "Negative Octal integer literal string");
ok(isNumber(-0144), "Negative Octal integer literal");
ok(isNumber("0xFF"), "Hexadecimal integer literal string");
ok(isNumber(0xFFF), "Hexadecimal integer literal");
ok(isNumber("-0xFF"), "Negative Hexadecimal integer literal string");
ok(isNumber(-0xFFF), "Negative Hexadecimal integer literal");
});
test("Foating-Point Literals", function() {
ok(isNumber("-1.6"), "Negative floating point string");
ok(isNumber("4.536"), "Positive floating point string");
ok(isNumber(-2.6), "Negative floating point number");
ok(isNumber(3.1415), "Positive floating point number");
ok(isNumber(8e5), "Exponential notation");
ok(isNumber("123e-2"), "Exponential notation string");
});
test("Non-Numeric values", function() {
equals(isNumber(""), false, "Empty string");
equals(isNumber(" "), false, "Whitespace characters string");
equals(isNumber("\t\t"), false, "Tab characters string");
equals(isNumber("abcdefghijklm1234567890"), false, "Alphanumeric character string");
equals(isNumber("xabcdefx"), false, "Non-numeric character string");
equals(isNumber(true), false, "Boolean true literal");
equals(isNumber(false), false, "Boolean false literal");
equals(isNumber("bcfed5.2"), false, "Number with preceding non-numeric characters");
equals(isNumber("7.2acdgs"), false, "Number with trailling non-numeric characters");
equals(isNumber(undefined), false, "Undefined value");
equals(isNumber(null), false, "Null value");
equals(isNumber(NaN), false, "NaN value");
equals(isNumber(Infinity), false, "Infinity primitive");
equals(isNumber(Number.POSITIVE_INFINITY), false, "Positive Infinity");
equals(isNumber(Number.NEGATIVE_INFINITY), false, "Negative Infinity");
equals(isNumber(new Date(2009, 1, 1)), false, "Date object");
equals(isNumber(new Object()), false, "Empty object");
equals(isNumber(function() {}), false, "Instance of a function");
equals(isNumber([]), false, "Empty Array");
equals(isNumber(["-10"]), false, "Array Negative integer string");
equals(isNumber(["0"]), false, "Array Zero string");
equals(isNumber(["5"]), false, "Array Positive integer string");
equals(isNumber([-16]), false, "Array Negative integer number");
equals(isNumber([0]), false, "Array Zero integer number");
equals(isNumber([32]), false, "Array Positive integer number");
equals(isNumber(["040"]), false, "Array Octal integer literal string");
equals(isNumber([0144]), false, "Array Octal integer literal");
equals(isNumber(["-040"]), false, "Array Negative Octal integer literal string");
equals(isNumber([-0144]), false, "Array Negative Octal integer literal");
equals(isNumber(["0xFF"]), false, "Array Hexadecimal integer literal string");
equals(isNumber([0xFFF]), false, "Array Hexadecimal integer literal");
equals(isNumber(["-0xFF"]), false, "Array Negative Hexadecimal integer literal string");
equals(isNumber([-0xFFF]), false, "Array Negative Hexadecimal integer literal");
equals(isNumber([1, 2]), false, "Array with more than 1 Positive interger number");
equals(isNumber([-1, -2]), false, "Array with more than 1 Negative interger number");
});
}
var functionsToTest = [
function(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
},
function(n) {
return !isNaN(n) && !isNaN(parseFloat(n));
},
function(n) {
return !isNaN((n));
},
function(n) {
return !isNaN(parseFloat(n));
},
function(n) {
return typeof(n) != "boolean" && !isNaN(n);
},
function(n) {
return parseFloat(n) === Number(n);
},
function(n) {
return parseInt(n) === Number(n);
},
function(n) {
return !isNaN(Number(String(n)));
},
function(n) {
return !isNaN(+('' + n));
},
function(n) {
return (+n) == n;
},
function(n) {
return n && /^-?\d+(\.\d+)?$/.test(n + '');
},
function(n) {
return isFinite(Number(String(n)));
},
function(n) {
return isFinite(String(n));
},
function(n) {
return !isNaN(n) && !isNaN(parseFloat(n)) && isFinite(n);
},
function(n) {
return parseFloat(n) == n;
},
function(n) {
return (n - 0) == n && n.length > 0;
},
function(n) {
return typeof n === 'number' && isFinite(n);
},
function(n) {
return !Array.isArray(n) && !isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}
];
// Examines the functionsToTest array, extracts the return statement of each function
// and fills the toTest select element.
var fillToTestSelect = function() {
for (var i = 0; i < functionsToTest.length; i++) {
var f = functionsToTest[i].toString();
var option = /[\s\S]*return ([\s\S]*);/.exec(f)[1];
$("#toTest").append('<option value="' + i + '">' + (i + 1) + '. ' + option + '</option>');
}
}
var performTest = function(functionNumber) {
reset(); // Reset previous test
$("#tests").html(""); //Clean test results
isNumber = functionsToTest[functionNumber]; // Override the isNumber global function with the one to test
testSuite(); // Run the test
// Get test results
var totalFail = 0;
var totalPass = 0;
$("b.fail").each(function() {
totalFail += Number($(this).html());
});
$("b.pass").each(function() {
totalPass += Number($(this).html());
});
$("#testresult").html(totalFail + " of " + (totalFail + totalPass) + " test failed.");
$("#banner").attr("class", "").addClass(totalFail > 0 ? "fail" : "pass");
}
return {
performTest: performTest,
fillToTestSelect: fillToTestSelect,
testSuite: testSuite
};
}();
$(document).ready(function() {
testHelper.fillToTestSelect();
testHelper.performTest(0);
$("#toTest").change(function() {
testHelper.performTest($(this).children(":selected").val());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>
<script src="https://rawgit.com/Xotic750/testrunner-old/master/testrunner.js" type="text/javascript"></script>
<link href="https://rawgit.com/Xotic750/testrunner-old/master/testrunner.css" rel="stylesheet" type="text/css">
<h1>isNumber Test Cases</h1>
<h2 id="banner" class="pass"></h2>
<h2 id="userAgent">Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11</h2>
<div id="currentFunction"></div>
<div id="selectFunction">
<label for="toTest" style="font-weight:bold; font-size:Large;">Select function to test:</label>
<select id="toTest" name="toTest">
</select>
</div>
<div id="testCode"></div>
<ol id="tests">
<li class="pass">
<strong>Integer Literals <b style="color:black;">(0, 10, 10)</b></strong>
<ol style="display: none;">
<li class="pass">Negative integer string</li>
<li class="pass">Zero string</li>
<li class="pass">Positive integer string</li>
<li class="pass">Negative integer number</li>
<li class="pass">Zero integer number</li>
<li class="pass">Positive integer number</li>
<li class="pass">Octal integer literal string</li>
<li class="pass">Octal integer literal</li>
<li class="pass">Hexadecimal integer literal string</li>
<li class="pass">Hexadecimal integer literal</li>
</ol>
</li>
<li class="pass">
<strong>Foating-Point Literals <b style="color:black;">(0, 6, 6)</b></strong>
<ol style="display: none;">
<li class="pass">Negative floating point string</li>
<li class="pass">Positive floating point string</li>
<li class="pass">Negative floating point number</li>
<li class="pass">Positive floating point number</li>
<li class="pass">Exponential notation</li>
<li class="pass">Exponential notation string</li>
</ol>
</li>
<li class="pass">
<strong>Non-Numeric values <b style="color:black;">(0, 18, 18)</b></strong>
<ol style="display: none;">
<li class="pass">Empty string: false</li>
<li class="pass">Whitespace characters string: false</li>
<li class="pass">Tab characters string: false</li>
<li class="pass">Alphanumeric character string: false</li>
<li class="pass">Non-numeric character string: false</li>
<li class="pass">Boolean true literal: false</li>
<li class="pass">Boolean false literal: false</li>
<li class="pass">Number with preceding non-numeric characters: false</li>
<li class="pass">Number with trailling non-numeric characters: false</li>
<li class="pass">Undefined value: false</li>
<li class="pass">Null value: false</li>
<li class="pass">NaN value: false</li>
<li class="pass">Infinity primitive: false</li>
<li class="pass">Positive Infinity: false</li>
<li class="pass">Negative Infinity: false</li>
<li class="pass">Date object: false</li>
<li class="pass">Empty object: false</li>
<li class="pass">Instance of a function: false</li>
</ol>
</li>
</ol>
<div id="main">
This page contains tests for a set of isNumber functions. To see them, take a look at the source.
</div>
<div>
<p class="result">Tests completed in 0 milliseconds.
<br>0 tests of 0 failed.</p>
</div>
function IsNumeric(num) {
return (num >=0 || num < 0);
}
This works for 0x23 type numbers as well.
Yeah, the built-in isNaN(object) will be much faster than any regex parsing, because it's built-in and compiled, instead of interpreted on the fly.
Although the results are somewhat different to what you're looking for (try it):
// IS NUMERIC
document.write(!isNaN('-1') + "<br />"); // true
document.write(!isNaN('-1.5') + "<br />"); // true
document.write(!isNaN('0') + "<br />"); // true
document.write(!isNaN('0.42') + "<br />"); // true
document.write(!isNaN('.42') + "<br />"); // true
document.write(!isNaN('99,999') + "<br />"); // false
document.write(!isNaN('0x89f') + "<br />"); // true
document.write(!isNaN('#abcdef') + "<br />"); // false
document.write(!isNaN('1.2.3') + "<br />"); // false
document.write(!isNaN('') + "<br />"); // true
document.write(!isNaN('blah') + "<br />"); // false
Use the function isNaN. I believe if you test for !isNaN(yourstringhere) it works fine for any of these situations.
Since jQuery 1.7, you can use jQuery.isNumeric():
$.isNumeric('-1'); // true
$.isNumeric('-1.5'); // true
$.isNumeric('0'); // true
$.isNumeric('0.42'); // true
$.isNumeric('.42'); // true
$.isNumeric('0x89f'); // true (valid hexa number)
$.isNumeric('99,999'); // false
$.isNumeric('#abcdef'); // false
$.isNumeric('1.2.3'); // false
$.isNumeric(''); // false
$.isNumeric('blah'); // false
Just note that unlike what you said, 0x89f is a valid number (hexa)
It can be done without RegExp as
function IsNumeric(data){
return parseFloat(data)==data;
}
To me, this is the best way:
isNumber : function(v){
return typeof v === 'number' && isFinite(v);
}
I realize the original question did not mention jQuery, but if you do use jQuery, you can do:
$.isNumeric(val)
Simple.
https://api.jquery.com/jQuery.isNumeric/ (as of jQuery 1.7)
return (input - 0) == input && input.length > 0;
didn't work for me. When I put in an alert and tested, input.length was undefined. I think there is no property to check integer length. So what I did was
var temp = '' + input;
return (input - 0) == input && temp.length > 0;
It worked fine.
If I'm not mistaken, this should match any valid JavaScript number value, excluding constants (Infinity, NaN) and the sign operators +/- (because they are not actually part of the number as far as I concerned, they are separate operators):
I needed this for a tokenizer, where sending the number to JavaScript for evaluation wasn't an option... It's definitely not the shortest possible regular expression, but I believe it catches all the finer subtleties of JavaScript's number syntax.
/^(?:(?:(?:[1-9]\d*|\d)\.\d*|(?:[1-9]\d*|\d)?\.\d+|(?:[1-9]\d*|\d))
(?:[e]\d+)?|0[0-7]+|0x[0-9a-f]+)$/i
Valid numbers would include:
- 0
- 00
- 01
- 10
- 0e1
- 0e01
- .0
- 0.
- .0e1
- 0.e1
- 0.e00
- 0xf
- 0Xf
Invalid numbers would be
- 00e1
- 01e1
- 00.0
- 00x0
- .
- .e0
Only problem I had with #CMS's answer is the exclusion of NaN and Infinity, which are useful numbers for many situations. One way to check for NaN's is to check for numeric values that don't equal themselves, NaN != NaN! So there are really 3 tests you'd like to deal with ...
function isNumber(n) {
n = parseFloat(n);
return !isNaN(n) || n != n;
}
function isFiniteNumber(n) {
n = parseFloat(n);
return !isNaN(n) && isFinite(n);
}
function isComparableNumber(n) {
n = parseFloat(n);
return (n >=0 || n < 0);
}
isFiniteNumber('NaN')
false
isFiniteNumber('OxFF')
true
isNumber('NaN')
true
isNumber(1/0-1/0)
true
isComparableNumber('NaN')
false
isComparableNumber('Infinity')
true
My isComparableNumber is pretty close to another elegant answer, but handles hex and other string representations of numbers.
I think parseFloat function can do all the work here. The function below passes all the tests on this page including isNumeric(Infinity) == true:
function isNumeric(n) {
return parseFloat(n) == n;
}
A couple of tests to add:
IsNumeric('01.05') => false
IsNumeric('1.') => false
IsNumeric('.') => false
I came up with this:
function IsNumeric(input) {
return /^-?(0|[1-9]\d*|(?=\.))(\.\d+)?$/.test(input);
}
The solution covers:
An optional negative sign at the beginning
A single zero, or one or more digits not starting with 0, or nothing so long as a period follows
A period that is followed by 1 or more numbers
I'd like to add the following:
1. IsNumeric('0x89f') => true
2. IsNumeric('075') => true
Positive hex numbers start with 0x and negative hex numbers start with -0x.
Positive oct numbers start with 0 and negative oct numbers start with -0.
This one takes most of what has already been mentioned into consideration, but includes hex and octal numbers, negative scientific, Infinity and has removed decimal scientific (4e3.2 is not valid).
function IsNumeric(input){
var RE = /^-?(0|INF|(0[1-7][0-7]*)|(0x[0-9a-fA-F]+)|((0|[1-9][0-9]*|(?=[\.,]))([\.,][0-9]+)?([eE]-?\d+)?))$/;
return (RE.test(input));
}
To check if a variable contains a valid number and not
just a String which looks like a number,
Number.isFinite(value) can be used.
This is part of the language since
ES2015
Examples:
Number.isFinite(Infinity) // false
Number.isFinite(NaN) // false
Number.isFinite(-Infinity) // false
Number.isFinite(0) // true
Number.isFinite(2e64) // true
Number.isFinite('0') // false
Number.isFinite(null) // false
An integer value can be verified by:
function isNumeric(value) {
var bool = isNaN(+value));
bool = bool || (value.indexOf('.') != -1);
bool = bool || (value.indexOf(",") != -1);
return !bool;
};
This way is easier and faster! All tests are checked!
Here's a lil bit improved version (probably the fastest way out there) that I use instead of exact jQuery's variant, I really don't know why don't they use this one:
function isNumeric(val) {
return !isNaN(+val) && isFinite(val);
}
The downside of jQuery's version is that if you pass a string with leading numerics and trailing letters like "123abc" the parseFloat | parseInt will extract the numeric fraction out and return 123, BUT, the second guard isFinite will fail it anyway.
With the unary + operator it will die on the very first guard since + throws NaN for such hybrids :)
A little performance yet I think a solid semantic gain.
My solution,
function isNumeric(input) {
var number = /^\-{0,1}(?:[0-9]+){0,1}(?:\.[0-9]+){0,1}$/i;
var regex = RegExp(number);
return regex.test(input) && input.length>0;
}
It appears to work in every situation, but I might be wrong.
I'm using simpler solution:
function isNumber(num) {
return parseFloat(num).toString() == num
}
This should work. Some of the functions provided here are flawed, also should be faster than any other function here.
function isNumeric(n)
{
var n2 = n;
n = parseFloat(n);
return (n!='NaN' && n2==n);
}
Explained:
Create a copy of itself, then converts the number into float, then compares itself with the original number, if it is still a number, (whether integer or float) , and matches the original number, that means, it is indeed a number.
It works with numeric strings as well as plain numbers. Does not work with hexadecimal numbers.
Warning: use at your own risk, no guarantees.
None of the answers return false for empty strings, a fix for that...
function is_numeric(n)
{
return (n != '' && !isNaN(parseFloat(n)) && isFinite(n));
}
function inNumeric(n){
return Number(n).toString() === n;
}
If n is numeric Number(n) will return the numeric value and toString() will turn it back to a string. But if n isn't numeric Number(n) will return NaN so it won't match the original n
Here's a dead-simple one (tested in Chrome, Firefox, and IE):
function isNumeric(x) {
return parseFloat(x) == x;
}
Test cases from question:
console.log('trues');
console.log(isNumeric('-1'));
console.log(isNumeric('-1.5'));
console.log(isNumeric('0'));
console.log(isNumeric('0.42'));
console.log(isNumeric('.42'));
console.log('falses');
console.log(isNumeric('99,999'));
console.log(isNumeric('0x89f'));
console.log(isNumeric('#abcdef'));
console.log(isNumeric('1.2.3'));
console.log(isNumeric(''));
console.log(isNumeric('blah'));
Some more test cases:
console.log('trues');
console.log(isNumeric(0));
console.log(isNumeric(-1));
console.log(isNumeric(-500));
console.log(isNumeric(15000));
console.log(isNumeric(0.35));
console.log(isNumeric(-10.35));
console.log(isNumeric(2.534e25));
console.log(isNumeric('2.534e25'));
console.log(isNumeric('52334'));
console.log(isNumeric('-234'));
console.log(isNumeric(Infinity));
console.log(isNumeric(-Infinity));
console.log(isNumeric('Infinity'));
console.log(isNumeric('-Infinity'));
console.log('falses');
console.log(isNumeric(NaN));
console.log(isNumeric({}));
console.log(isNumeric([]));
console.log(isNumeric(''));
console.log(isNumeric('one'));
console.log(isNumeric(true));
console.log(isNumeric(false));
console.log(isNumeric());
console.log(isNumeric(undefined));
console.log(isNumeric(null));
console.log(isNumeric('-234aa'));
Note that it considers infinity a number.
I realize this has been answered many times, but the following is a decent candidate which can be useful in some scenarios.
it should be noted that it assumes that '.42' is NOT a number, and '4.' is NOT a number, so this should be taken into account.
function isDecimal(x) {
return '' + x === '' + +x;
}
function isInteger(x) {
return '' + x === '' + parseInt(x);
}
The isDecimal passes the following test:
function testIsNumber(f) {
return f('-1') && f('-1.5') && f('0') && f('0.42')
&& !f('.42') && !f('99,999') && !f('0x89f')
&& !f('#abcdef') && !f('1.2.3') && !f('') && !f('blah');
}
The idea here is that every number or integer has one "canonical" string representation, and every non-canonical representation should be rejected. So we cast to a number and back, and see if the result is the original string.
Whether these functions are useful for you depends on the use case. One feature is that distinct strings represent distinct numbers (if both pass the isNumber() test).
This is relevant e.g. for numbers as object property names.
var obj = {};
obj['4'] = 'canonical 4';
obj['04'] = 'alias of 4';
obj[4]; // prints 'canonical 4' to the console.
knockoutJs Inbuild library validation functions
By extending it the field get validated
1) number
self.number = ko.observable(numberValue).extend({ number: true});
TestCase
numberValue = '0.0' --> true
numberValue = '0' --> true
numberValue = '25' --> true
numberValue = '-1' --> true
numberValue = '-3.5' --> true
numberValue = '11.112' --> true
numberValue = '0x89f' --> false
numberValue = '' --> false
numberValue = 'sfsd' --> false
numberValue = 'dg##$' --> false
2) digit
self.number = ko.observable(numberValue).extend({ digit: true});
TestCase
numberValue = '0' --> true
numberValue = '25' --> true
numberValue = '0.0' --> false
numberValue = '-1' --> false
numberValue = '-3.5' --> false
numberValue = '11.112' --> false
numberValue = '0x89f' --> false
numberValue = '' --> false
numberValue = 'sfsd' --> false
numberValue = 'dg##$' --> false
3) min and max
self.number = ko.observable(numberValue).extend({ min: 5}).extend({ max: 10});
This field accept value between 5 and 10 only
TestCase
numberValue = '5' --> true
numberValue = '6' --> true
numberValue = '6.5' --> true
numberValue = '9' --> true
numberValue = '11' --> false
numberValue = '0' --> false
numberValue = '' --> false
If you need to validate a special set of decimals y
you can use this simple javascript:
http://codesheet.org/codesheet/x1kI7hAD
<input type="text" name="date" value="" pattern="[0-9]){1,2}(\.){1}([0-9]){2}" maxlength="6" placeholder="od npr.: 16.06" onchange="date(this);" />
The Javascript:
function date(inputField) {
var isValid = /^([0-9]){1,2}(\.){1}([0-9]){2}$/.test(inputField.value);
if (isValid) {
inputField.style.backgroundColor = '#bfa';
} else {
inputField.style.backgroundColor = '#fba';
}
return isValid;
}
Related
How to Reliably Check if a Javascript String is a Number
How do you determine if a string represents a number? The straightforward and potentially naive way is this: function is_number(my_str) { return !isNaN(parseInt(my_str)); } However, the above does not work. Notice that the following all return true: is_number("3, 4, 5"); is_number("3, (123)"); is_number("3, 123)"); is_number("3, (123) (and foo bar)"); is_number("3 apples and 2 oranges"); The issue is that parseInt seems to only look at the first word. Any idea on a more comprehensive solution here?
You can use Number(). parseInt and parseFloat converts String to Number if first character is a number. But Number() checks for whole String.Number return NaN if whole string is not number function is_number(my_str) { return !isNaN(Number(my_str)) && Boolean(my_str) || my_str == 0; } console.log(is_number("3, 4, 5")); console.log(is_number("3, (123)")); console.log(is_number("3, 123)")); console.log(is_number("3, (123) (and foo bar)")); console.log(is_number("3 apples and 2 oranges")); console.log(is_number(null)); console.log(is_number(undefined)); console.log(is_number(0)); console.log(is_number('0'));
All you need is Number console.log(Number("3, 4, 5") || false) console.log(Number("3, (123)") || false) console.log(Number("3, 123)") || false) console.log(Number('123') || false)
Here's my regular-expression based effort: function isNumber (string) { return /^-?[0-9]+(?:\.[0-9]+)?(?:[eE][-+]?[0-9]+)?$/.test(string); } Includes support for leading sign, decimal places and exponent. If it returns true, the string can be converted to a number using JSON.parse: function isNumber (string) { return /^-?[0-9]+(?:\.[0-9]+)?(?:[eE][-+]?[0-9]+)?$/.test(string); } function convertNumber (string) { if (isNumber(string)) { return JSON.parse(string); } } [ '0', '1.2', '-3.4', '5.6789e100', '0.1e-100', '0.1e+100', ].forEach(string => { console.log(`isNumber('${string}'):`, isNumber(string)); console.log(`typeof convertNumber('${string}'):`, typeof convertNumber(string)); });
How to tell if "123#231.23" is not a number in javascript?
parseInt("123#231.23") returns 123, which is a number. There are tons of functions out there to detect if something is a number or not already, but they all depend on parseInt. What is another generic way of detecting that this is not an integer without using regex?
if (isNaN("123#231.23")) { alert("IsNaN - not a number"); } else { alert ("it is a number"); } I'm assuming that OP need to distinguish if input is a number or not. If input is float or integer looks irrelevant to his problem. Maybe, I'm wrong... EDIT: Alright, to keep everyone happy, integer in javasript is pretty big. How big integer is in javascript check here. Asking if something is integer is asking is it a whole number between 9007199254740992 and -9007199254740992. Wholeness of the number you may check using modulus % $("#cmd").click(function (e) { ChectIfInteger( $("#txt").val() ) }); function ChectIfInteger(myval){ if (isNaN(myval)){ alert("not integer (not number)") } else{ //it is a number but it is integer? if( myval % 1 == 0 ){ if (myval <= 9007199254740992 && myval >= -9007199254740992) { alert("it is integer in javascript"); } else{ alert ("not integer"); } } else{ alert("nope, not integer"); } } } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input type="text" id="txt"/> <input type="button" id="cmd" value="test input">
Convert back to String and compare: String(parseInt("123"))=="123" // true String(parseInt("123.sdfs"))=="123.sdfs" //false
If you really want to check "for valid integer" you must combine isNaN with something else like this: function isValidInteger(numberToTest) { return !(isNaN(numberToTest) || String(parseInt(numberToTest)) !== numberToTest.toString()); } This will evaluate like: console.log(isValidInteger('123#231.23')); // false console.log(isValidInteger('123231.23')); // false console.log(isValidInteger('12323')); // true console.log(isValidInteger(1e-1)); // false console.log(isValidInteger('1e-1')); // false And this work even with numbers. Here is PLNKR to test.
I think this is the best way to test for integers: function isInt(str) { if (typeof str !== 'number' && typeof str !== 'string') { return false; } return str % 1 === 0; } Just note that strings / numbers like "123.0" evaluates to true.
Here's yet another one that doesn't rely on string stuff: function looksLikeInteger(n) { return +n == n && +n === ~~n; } Probably should be called "looksLikeJavaScriptInteger" because it only works for 32-bit integers. It coerces to numeric with unary + and then checks for equality (so ugly strings and objects are tossed out there) and then checks to make sure that the numeric value doesn't change when coerced to an integer.
isFinite of space giving true value
I am trying to validate a price field. I was trying this: var productId = document.getElementById("productId"); var productName = document.getElementById("productName"); var productPrice = document.getElementById("price"); alert(isFinite(productPrice.value)); if(isNaN(productPrice.value)||!isFinite(productPrice.value)){ error = document.getElementById("priceError"); error.innerHTML = "Please enter correct value"; productPrice.style.border="thin solid red"; }else{ error = document.getElementById("priceError"); error.innerHTML = ""; } The line alert is giving me true when the input is space/ multiple spaces only. This is my HTML page. <td>Price</td> <td><input type = "text" id = "price" size = "14"/></td> Thanks
Why this happens i cant say, but this code should solve the problem isFinite(parseFloat(" ")) // false // because --> parseFloat(" "); // => result NaN // tested in Chrome 27+ on Win7 in the MDN refernce of isNaN here it says isNaN(" "); // false: a string with spaces is converted to 0 which is not NaN Update: in the Reference of isFinite found Here it states that isFinite only returns false if the argument is: NaN positive infinity, (Number.POSITIVE_INFINITY) negative infinity (Number.NEGATIVE_INFINITY) In any other Case it returns true. (like Paul S mentioned) Now i Think i got all loose ends, and in that course learned something. :)
with window.isFinite, you must be aware of the issues that window.isNaN suffers from when coercing types. window.IsNaN Summary Determines whether a value is NaN or not. Be careful, this function is broken. You may be interested in ECMAScript 6 Number.isNaN. Examples isNaN(NaN); // true isNaN(undefined); // true isNaN({}); // true isNaN(true); // false isNaN(null); // false isNaN(37); // false // strings isNaN("37"); // false: "37" is converted to the number 37 which is not NaN isNaN("37.37"); // false: "37.37" is converted to the number 37.37 which is not NaN isNaN(""); // false: the empty string is converted to 0 which is not NaN isNaN(" "); // false: a string with spaces is converted to 0 which is not NaN // This is a false positive and the reason why isNaN is not entirely reliable isNaN("blabla") // true: "blabla" is converted to a number. Parsing this as a number fails and returns NaN In ECMAScript 6 there are new methods Number.isNaN and Number.isFinite that address these issues. (of course these are not available in many browsers) Number.isFinite is equivalent to function isFinite(number) { return typeof number === "number" && window.isFinite(number); } So as a solution, you would need to consider something like this (cross-browser). Note: this solution will still allow you to enter hexadecimal or scientific notations, "0xA", "1e10" Javascript function isFinite(number) { return typeof number === "number" && window.isFinite(number); } function trim(string) { return string.replace(/^\s+|\s+$/g, ""); } var price = document.getElementById("price"); price.onchange = function (e) { var evt = e || window.event, target = evt.target || evt.srcElement, value = trim(target.value) || "NaN", number = +value; console.log("number:", number); console.log("isFinite:", isFinite(number)); } On jsfiddle
You could do it using reqular expression. Try this. function validatePrice() { var el = document.getElementById('price'); if ( el.value.length < 14 && /^ *\+?\d+ *$/.test( el.value ) ) { return true; } return false; } This function checks if the input is positive integer. I didnt know if you want floated values also. If you do, switch the regex to this /^ *+?\d+((.|,)\d+)? *$/
Javascript string/integer comparisons
I store some parameters client-side in HTML and then need to compare them as integers. Unfortunately I have come across a serious bug that I cannot explain. The bug seems to be that my JS reads parameters as strings rather than integers, causing my integer comparisons to fail. I have generated a small example of the error, which I also can't explain. The following returns 'true' when run: console.log("2" > "10")
Parse the string into an integer using parseInt: javascript:alert(parseInt("2", 10)>parseInt("10", 10))
Checking that strings are integers is separate to comparing if one is greater or lesser than another. You should always compare number with number and string with string as the algorithm for dealing with mixed types not easy to remember. '00100' < '1' // true as they are both strings so only the first zero of '00100' is compared to '1' and because it's charCode is lower, it evaluates as lower. However: '00100' < 1 // false as the RHS is a number, the LHS is converted to number before the comparision. A simple integer check is: function isInt(n) { return /^[+-]?\d+$/.test(n); } It doesn't matter if n is a number or integer, it will be converted to a string before the test. If you really care about performance, then: var isInt = (function() { var re = /^[+-]?\d+$/; return function(n) { return re.test(n); } }()); Noting that numbers like 1.0 will return false. If you want to count such numbers as integers too, then: var isInt = (function() { var re = /^[+-]?\d+$/; var re2 = /\.0+$/; return function(n) { return re.test((''+ n).replace(re2,'')); } }()); Once that test is passed, converting to number for comparison can use a number of methods. I don't like parseInt() because it will truncate floats to make them look like ints, so all the following will be "equal": parseInt(2.9) == parseInt('002',10) == parseInt('2wewe') and so on. Once numbers are tested as integers, you can use the unary + operator to convert them to numbers in the comparision: if (isInt(a) && isInt(b)) { if (+a < +b) { // a and b are integers and a is less than b } } Other methods are: Number(a); // liked by some because it's clear what is happening a * 1 // Not really obvious but it works, I don't like it
Comparing Numbers to String Equivalents Without Using parseInt console.log(Number('2') > Number('10')); console.log( ('2'/1) > ('10'/1) ); var item = { id: 998 }, id = '998'; var isEqual = (item.id.toString() === id.toString()); isEqual;
use parseInt and compare like below: javascript:alert(parseInt("2")>parseInt("10"))
Always remember when we compare two strings. the comparison happens on chacracter basis. so '2' > '12' is true because the comparison will happen as '2' > '1' and in alphabetical way '2' is always greater than '1' as unicode. SO it will comeout true. I hope this helps.
You can use Number() function also since it converts the object argument to a number that represents the object's value. Eg: javascript:alert( Number("2") > Number("10"))
+ operator will coerce the string to a number. console.log( +"2" > +"10" )
The answer is simple. Just divide string by 1. Examples: "2" > "10" - true but "2"/1 > "10"/1 - false Also you can check if string value really is number: !isNaN("1"/1) - true (number) !isNaN("1a"/1) - false (string) !isNaN("01"/1) - true (number) !isNaN(" 1"/1) - true (number) !isNaN(" 1abc"/1) - false (string) But !isNaN(""/1) - true (but string) Solution number !== "" && !isNaN(number/1)
The alert() wants to display a string, so it will interpret "2">"10" as a string. Use the following: var greater = parseInt("2") > parseInt("10"); alert("Is greater than? " + greater); var less = parseInt("2") < parseInt("10"); alert("Is less than? " + less);
Validate decimal numbers in JavaScript - IsNumeric()
What's the cleanest, most effective way to validate decimal numbers in JavaScript? Bonus points for: Clarity. Solution should be clean and simple. Cross-platform. Test cases: 01. IsNumeric('-1') => true 02. IsNumeric('-1.5') => true 03. IsNumeric('0') => true 04. IsNumeric('0.42') => true 05. IsNumeric('.42') => true 06. IsNumeric('99,999') => false 07. IsNumeric('0x89f') => false 08. IsNumeric('#abcdef') => false 09. IsNumeric('1.2.3') => false 10. IsNumeric('') => false 11. IsNumeric('blah') => false
#Joel's answer is pretty close, but it will fail in the following cases: // Whitespace strings: IsNumeric(' ') == true; IsNumeric('\t\t') == true; IsNumeric('\n\r') == true; // Number literals: IsNumeric(-1) == false; IsNumeric(0) == false; IsNumeric(1.1) == false; IsNumeric(8e5) == false; Some time ago I had to implement an IsNumeric function, to find out if a variable contained a numeric value, regardless of its type, it could be a String containing a numeric value (I had to consider also exponential notation, etc.), a Number object, virtually anything could be passed to that function, I couldn't make any type assumptions, taking care of type coercion (eg. +true == 1; but true shouldn't be considered as "numeric"). I think is worth sharing this set of +30 unit tests made to numerous function implementations, and also share the one that passes all my tests: function isNumeric(n) { return !isNaN(parseFloat(n)) && isFinite(n); } P.S. isNaN & isFinite have a confusing behavior due to forced conversion to number. In ES6, Number.isNaN & Number.isFinite would fix these issues. Keep that in mind when using them. Update : Here's how jQuery does it now (2.2-stable): isNumeric: function(obj) { var realStringObj = obj && obj.toString(); return !jQuery.isArray(obj) && (realStringObj - parseFloat(realStringObj) + 1) >= 0; } Update : Angular 4.3: export function isNumeric(value: any): boolean { return !isNaN(value - parseFloat(value)); }
Arrrgh! Don't listen to the regular expression answers. RegEx is icky for this, and I'm not talking just performance. It's so easy to make subtle, impossible to spot mistakes with your regular expression. If you can't use isNaN(), this should work much better: function IsNumeric(input) { return (input - 0) == input && (''+input).trim().length > 0; } Here's how it works: The (input - 0) expression forces JavaScript to do type coercion on your input value; it must first be interpreted as a number for the subtraction operation. If that conversion to a number fails, the expression will result in NaN. This numeric result is then compared to the original value you passed in. Since the left hand side is now numeric, type coercion is again used. Now that the input from both sides was coerced to the same type from the same original value, you would think they should always be the same (always true). However, there's a special rule that says NaN is never equal to NaN, and so a value that can't be converted to a number (and only values that cannot be converted to numbers) will result in false. The check on the length is for a special case involving empty strings. Also note that it falls down on your 0x89f test, but that's because in many environments that's an okay way to define a number literal. If you want to catch that specific scenario you could add an additional check. Even better, if that's your reason for not using isNaN() then just wrap your own function around isNaN() that can also do the additional check. In summary, if you want to know if a value can be converted to a number, actually try to convert it to a number. I went back and did some research for why a whitespace string did not have the expected output, and I think I get it now: an empty string is coerced to 0 rather than NaN. Simply trimming the string before the length check will handle this case. Running the unit tests against the new code and it only fails on the infinity and boolean literals, and the only time that should be a problem is if you're generating code (really, who would type in a literal and check if it's numeric? You should know), and that would be some strange code to generate. But, again, the only reason ever to use this is if for some reason you have to avoid isNaN().
This way seems to work well: function IsNumeric(input){ var RE = /^-{0,1}\d*\.{0,1}\d+$/; return (RE.test(input)); } In one line: const IsNumeric = (num) => /^-{0,1}\d*\.{0,1}\d+$/.test(num); And to test it: const IsNumeric = (num) => /^-{0,1}\d*\.{0,1}\d+$/.test(num); function TestIsNumeric(){ var results = '' results += (IsNumeric('-1')?"Pass":"Fail") + ": IsNumeric('-1') => true\n"; results += (IsNumeric('-1.5')?"Pass":"Fail") + ": IsNumeric('-1.5') => true\n"; results += (IsNumeric('0')?"Pass":"Fail") + ": IsNumeric('0') => true\n"; results += (IsNumeric('0.42')?"Pass":"Fail") + ": IsNumeric('0.42') => true\n"; results += (IsNumeric('.42')?"Pass":"Fail") + ": IsNumeric('.42') => true\n"; results += (!IsNumeric('99,999')?"Pass":"Fail") + ": IsNumeric('99,999') => false\n"; results += (!IsNumeric('0x89f')?"Pass":"Fail") + ": IsNumeric('0x89f') => false\n"; results += (!IsNumeric('#abcdef')?"Pass":"Fail") + ": IsNumeric('#abcdef') => false\n"; results += (!IsNumeric('1.2.3')?"Pass":"Fail") + ": IsNumeric('1.2.3') => false\n"; results += (!IsNumeric('')?"Pass":"Fail") + ": IsNumeric('') => false\n"; results += (!IsNumeric('blah')?"Pass":"Fail") + ": IsNumeric('blah') => false\n"; return results; } console.log(TestIsNumeric()); .as-console-wrapper { max-height: 100% !important; top: 0; } I borrowed that regex from http://www.codetoad.com/javascript/isnumeric.asp. Explanation: /^ match beginning of string -{0,1} optional negative sign \d* optional digits \.{0,1} optional decimal point \d+ at least one digit $/ match end of string
Yahoo! UI uses this: isNumber: function(o) { return typeof o === 'number' && isFinite(o); }
The accepted answer failed your test #7 and I guess it's because you changed your mind. So this is a response to the accepted answer, with which I had issues. During some projects, I have needed to validate some data and be as certain as possible that it is a javascript numerical value that can be used in mathematical operations. jQuery and some other javascript libraries already include such a function, usually called isNumeric. There is also a post on stackoverflow that has been widely accepted as the answer, the same general routine that the aforementioned libraries are using. function isNumber(n) { return !isNaN(parseFloat(n)) && isFinite(n); } First, the code above would return true if the argument was an array of length 1, and that single element was of a type deemed as numeric by the above logic. In my opinion, if it's an array then its not numeric. To alleviate this problem, I added a check to discount arrays from the logic function isNumber(n) { return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n); } Of course, you could also use Array.isArray, jquery $.isArray or prototype Object.isArray instead of Object.prototype.toString.call(n) !== '[object Array]' My second issue was that Negative Hexadecimal integer literal strings ("-0xA" -> -10) were not being counted as numeric. However, Positive Hexadecimal integer literal strings ("0xA" -> 10) were treated as numeric. I needed both to be valid numeric. I then modified the logic to take this into account. function isNumber(n) { return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, '')); } If you are worried about the creation of the regex each time the function is called then you could rewrite it within a closure, something like this var isNumber = (function () { var rx = /^-/; return function (n) { return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(rx, '')); }; }()); I then took CMSs +30 test cases and cloned the testing on jsfiddle and added my extra test cases and my above-described solution. It may not replace the widely accepted/used answer but if this is more of what you are expecting as results from your isNumeric function then hopefully this will be of some help. EDIT: As pointed out by Bergi, there are other possible objects that could be considered numeric and it would be better to whitelist than a blacklist. With this in mind, I would add to the criteria. I want my isNumeric function to consider only Numbers or Strings With this in mind, it would be better to use function isNumber(n) { return (Object.prototype.toString.call(n) === '[object Number]' || Object.prototype.toString.call(n) === '[object String]') &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, '')); } Test the solutions var testHelper = function() { var testSuite = function() { test("Integer Literals", function() { ok(isNumber("-10"), "Negative integer string"); ok(isNumber("0"), "Zero string"); ok(isNumber("5"), "Positive integer string"); ok(isNumber(-16), "Negative integer number"); ok(isNumber(0), "Zero integer number"); ok(isNumber(32), "Positive integer number"); ok(isNumber("040"), "Octal integer literal string"); ok(isNumber(0144), "Octal integer literal"); ok(isNumber("-040"), "Negative Octal integer literal string"); ok(isNumber(-0144), "Negative Octal integer literal"); ok(isNumber("0xFF"), "Hexadecimal integer literal string"); ok(isNumber(0xFFF), "Hexadecimal integer literal"); ok(isNumber("-0xFF"), "Negative Hexadecimal integer literal string"); ok(isNumber(-0xFFF), "Negative Hexadecimal integer literal"); }); test("Foating-Point Literals", function() { ok(isNumber("-1.6"), "Negative floating point string"); ok(isNumber("4.536"), "Positive floating point string"); ok(isNumber(-2.6), "Negative floating point number"); ok(isNumber(3.1415), "Positive floating point number"); ok(isNumber(8e5), "Exponential notation"); ok(isNumber("123e-2"), "Exponential notation string"); }); test("Non-Numeric values", function() { equals(isNumber(""), false, "Empty string"); equals(isNumber(" "), false, "Whitespace characters string"); equals(isNumber("\t\t"), false, "Tab characters string"); equals(isNumber("abcdefghijklm1234567890"), false, "Alphanumeric character string"); equals(isNumber("xabcdefx"), false, "Non-numeric character string"); equals(isNumber(true), false, "Boolean true literal"); equals(isNumber(false), false, "Boolean false literal"); equals(isNumber("bcfed5.2"), false, "Number with preceding non-numeric characters"); equals(isNumber("7.2acdgs"), false, "Number with trailling non-numeric characters"); equals(isNumber(undefined), false, "Undefined value"); equals(isNumber(null), false, "Null value"); equals(isNumber(NaN), false, "NaN value"); equals(isNumber(Infinity), false, "Infinity primitive"); equals(isNumber(Number.POSITIVE_INFINITY), false, "Positive Infinity"); equals(isNumber(Number.NEGATIVE_INFINITY), false, "Negative Infinity"); equals(isNumber(new Date(2009, 1, 1)), false, "Date object"); equals(isNumber(new Object()), false, "Empty object"); equals(isNumber(function() {}), false, "Instance of a function"); equals(isNumber([]), false, "Empty Array"); equals(isNumber(["-10"]), false, "Array Negative integer string"); equals(isNumber(["0"]), false, "Array Zero string"); equals(isNumber(["5"]), false, "Array Positive integer string"); equals(isNumber([-16]), false, "Array Negative integer number"); equals(isNumber([0]), false, "Array Zero integer number"); equals(isNumber([32]), false, "Array Positive integer number"); equals(isNumber(["040"]), false, "Array Octal integer literal string"); equals(isNumber([0144]), false, "Array Octal integer literal"); equals(isNumber(["-040"]), false, "Array Negative Octal integer literal string"); equals(isNumber([-0144]), false, "Array Negative Octal integer literal"); equals(isNumber(["0xFF"]), false, "Array Hexadecimal integer literal string"); equals(isNumber([0xFFF]), false, "Array Hexadecimal integer literal"); equals(isNumber(["-0xFF"]), false, "Array Negative Hexadecimal integer literal string"); equals(isNumber([-0xFFF]), false, "Array Negative Hexadecimal integer literal"); equals(isNumber([1, 2]), false, "Array with more than 1 Positive interger number"); equals(isNumber([-1, -2]), false, "Array with more than 1 Negative interger number"); }); } var functionsToTest = [ function(n) { return !isNaN(parseFloat(n)) && isFinite(n); }, function(n) { return !isNaN(n) && !isNaN(parseFloat(n)); }, function(n) { return !isNaN((n)); }, function(n) { return !isNaN(parseFloat(n)); }, function(n) { return typeof(n) != "boolean" && !isNaN(n); }, function(n) { return parseFloat(n) === Number(n); }, function(n) { return parseInt(n) === Number(n); }, function(n) { return !isNaN(Number(String(n))); }, function(n) { return !isNaN(+('' + n)); }, function(n) { return (+n) == n; }, function(n) { return n && /^-?\d+(\.\d+)?$/.test(n + ''); }, function(n) { return isFinite(Number(String(n))); }, function(n) { return isFinite(String(n)); }, function(n) { return !isNaN(n) && !isNaN(parseFloat(n)) && isFinite(n); }, function(n) { return parseFloat(n) == n; }, function(n) { return (n - 0) == n && n.length > 0; }, function(n) { return typeof n === 'number' && isFinite(n); }, function(n) { return !Array.isArray(n) && !isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, '')); } ]; // Examines the functionsToTest array, extracts the return statement of each function // and fills the toTest select element. var fillToTestSelect = function() { for (var i = 0; i < functionsToTest.length; i++) { var f = functionsToTest[i].toString(); var option = /[\s\S]*return ([\s\S]*);/.exec(f)[1]; $("#toTest").append('<option value="' + i + '">' + (i + 1) + '. ' + option + '</option>'); } } var performTest = function(functionNumber) { reset(); // Reset previous test $("#tests").html(""); //Clean test results isNumber = functionsToTest[functionNumber]; // Override the isNumber global function with the one to test testSuite(); // Run the test // Get test results var totalFail = 0; var totalPass = 0; $("b.fail").each(function() { totalFail += Number($(this).html()); }); $("b.pass").each(function() { totalPass += Number($(this).html()); }); $("#testresult").html(totalFail + " of " + (totalFail + totalPass) + " test failed."); $("#banner").attr("class", "").addClass(totalFail > 0 ? "fail" : "pass"); } return { performTest: performTest, fillToTestSelect: fillToTestSelect, testSuite: testSuite }; }(); $(document).ready(function() { testHelper.fillToTestSelect(); testHelper.performTest(0); $("#toTest").change(function() { testHelper.performTest($(this).children(":selected").val()); }); }); <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script> <script src="https://rawgit.com/Xotic750/testrunner-old/master/testrunner.js" type="text/javascript"></script> <link href="https://rawgit.com/Xotic750/testrunner-old/master/testrunner.css" rel="stylesheet" type="text/css"> <h1>isNumber Test Cases</h1> <h2 id="banner" class="pass"></h2> <h2 id="userAgent">Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11</h2> <div id="currentFunction"></div> <div id="selectFunction"> <label for="toTest" style="font-weight:bold; font-size:Large;">Select function to test:</label> <select id="toTest" name="toTest"> </select> </div> <div id="testCode"></div> <ol id="tests"> <li class="pass"> <strong>Integer Literals <b style="color:black;">(0, 10, 10)</b></strong> <ol style="display: none;"> <li class="pass">Negative integer string</li> <li class="pass">Zero string</li> <li class="pass">Positive integer string</li> <li class="pass">Negative integer number</li> <li class="pass">Zero integer number</li> <li class="pass">Positive integer number</li> <li class="pass">Octal integer literal string</li> <li class="pass">Octal integer literal</li> <li class="pass">Hexadecimal integer literal string</li> <li class="pass">Hexadecimal integer literal</li> </ol> </li> <li class="pass"> <strong>Foating-Point Literals <b style="color:black;">(0, 6, 6)</b></strong> <ol style="display: none;"> <li class="pass">Negative floating point string</li> <li class="pass">Positive floating point string</li> <li class="pass">Negative floating point number</li> <li class="pass">Positive floating point number</li> <li class="pass">Exponential notation</li> <li class="pass">Exponential notation string</li> </ol> </li> <li class="pass"> <strong>Non-Numeric values <b style="color:black;">(0, 18, 18)</b></strong> <ol style="display: none;"> <li class="pass">Empty string: false</li> <li class="pass">Whitespace characters string: false</li> <li class="pass">Tab characters string: false</li> <li class="pass">Alphanumeric character string: false</li> <li class="pass">Non-numeric character string: false</li> <li class="pass">Boolean true literal: false</li> <li class="pass">Boolean false literal: false</li> <li class="pass">Number with preceding non-numeric characters: false</li> <li class="pass">Number with trailling non-numeric characters: false</li> <li class="pass">Undefined value: false</li> <li class="pass">Null value: false</li> <li class="pass">NaN value: false</li> <li class="pass">Infinity primitive: false</li> <li class="pass">Positive Infinity: false</li> <li class="pass">Negative Infinity: false</li> <li class="pass">Date object: false</li> <li class="pass">Empty object: false</li> <li class="pass">Instance of a function: false</li> </ol> </li> </ol> <div id="main"> This page contains tests for a set of isNumber functions. To see them, take a look at the source. </div> <div> <p class="result">Tests completed in 0 milliseconds. <br>0 tests of 0 failed.</p> </div>
function IsNumeric(num) { return (num >=0 || num < 0); } This works for 0x23 type numbers as well.
Yeah, the built-in isNaN(object) will be much faster than any regex parsing, because it's built-in and compiled, instead of interpreted on the fly. Although the results are somewhat different to what you're looking for (try it): // IS NUMERIC document.write(!isNaN('-1') + "<br />"); // true document.write(!isNaN('-1.5') + "<br />"); // true document.write(!isNaN('0') + "<br />"); // true document.write(!isNaN('0.42') + "<br />"); // true document.write(!isNaN('.42') + "<br />"); // true document.write(!isNaN('99,999') + "<br />"); // false document.write(!isNaN('0x89f') + "<br />"); // true document.write(!isNaN('#abcdef') + "<br />"); // false document.write(!isNaN('1.2.3') + "<br />"); // false document.write(!isNaN('') + "<br />"); // true document.write(!isNaN('blah') + "<br />"); // false
Use the function isNaN. I believe if you test for !isNaN(yourstringhere) it works fine for any of these situations.
Since jQuery 1.7, you can use jQuery.isNumeric(): $.isNumeric('-1'); // true $.isNumeric('-1.5'); // true $.isNumeric('0'); // true $.isNumeric('0.42'); // true $.isNumeric('.42'); // true $.isNumeric('0x89f'); // true (valid hexa number) $.isNumeric('99,999'); // false $.isNumeric('#abcdef'); // false $.isNumeric('1.2.3'); // false $.isNumeric(''); // false $.isNumeric('blah'); // false Just note that unlike what you said, 0x89f is a valid number (hexa)
It can be done without RegExp as function IsNumeric(data){ return parseFloat(data)==data; }
To me, this is the best way: isNumber : function(v){ return typeof v === 'number' && isFinite(v); }
I realize the original question did not mention jQuery, but if you do use jQuery, you can do: $.isNumeric(val) Simple. https://api.jquery.com/jQuery.isNumeric/ (as of jQuery 1.7)
return (input - 0) == input && input.length > 0; didn't work for me. When I put in an alert and tested, input.length was undefined. I think there is no property to check integer length. So what I did was var temp = '' + input; return (input - 0) == input && temp.length > 0; It worked fine.
If I'm not mistaken, this should match any valid JavaScript number value, excluding constants (Infinity, NaN) and the sign operators +/- (because they are not actually part of the number as far as I concerned, they are separate operators): I needed this for a tokenizer, where sending the number to JavaScript for evaluation wasn't an option... It's definitely not the shortest possible regular expression, but I believe it catches all the finer subtleties of JavaScript's number syntax. /^(?:(?:(?:[1-9]\d*|\d)\.\d*|(?:[1-9]\d*|\d)?\.\d+|(?:[1-9]\d*|\d)) (?:[e]\d+)?|0[0-7]+|0x[0-9a-f]+)$/i Valid numbers would include: - 0 - 00 - 01 - 10 - 0e1 - 0e01 - .0 - 0. - .0e1 - 0.e1 - 0.e00 - 0xf - 0Xf Invalid numbers would be - 00e1 - 01e1 - 00.0 - 00x0 - . - .e0
Only problem I had with #CMS's answer is the exclusion of NaN and Infinity, which are useful numbers for many situations. One way to check for NaN's is to check for numeric values that don't equal themselves, NaN != NaN! So there are really 3 tests you'd like to deal with ... function isNumber(n) { n = parseFloat(n); return !isNaN(n) || n != n; } function isFiniteNumber(n) { n = parseFloat(n); return !isNaN(n) && isFinite(n); } function isComparableNumber(n) { n = parseFloat(n); return (n >=0 || n < 0); } isFiniteNumber('NaN') false isFiniteNumber('OxFF') true isNumber('NaN') true isNumber(1/0-1/0) true isComparableNumber('NaN') false isComparableNumber('Infinity') true My isComparableNumber is pretty close to another elegant answer, but handles hex and other string representations of numbers.
I think parseFloat function can do all the work here. The function below passes all the tests on this page including isNumeric(Infinity) == true: function isNumeric(n) { return parseFloat(n) == n; }
A couple of tests to add: IsNumeric('01.05') => false IsNumeric('1.') => false IsNumeric('.') => false I came up with this: function IsNumeric(input) { return /^-?(0|[1-9]\d*|(?=\.))(\.\d+)?$/.test(input); } The solution covers: An optional negative sign at the beginning A single zero, or one or more digits not starting with 0, or nothing so long as a period follows A period that is followed by 1 or more numbers
I'd like to add the following: 1. IsNumeric('0x89f') => true 2. IsNumeric('075') => true Positive hex numbers start with 0x and negative hex numbers start with -0x. Positive oct numbers start with 0 and negative oct numbers start with -0. This one takes most of what has already been mentioned into consideration, but includes hex and octal numbers, negative scientific, Infinity and has removed decimal scientific (4e3.2 is not valid). function IsNumeric(input){ var RE = /^-?(0|INF|(0[1-7][0-7]*)|(0x[0-9a-fA-F]+)|((0|[1-9][0-9]*|(?=[\.,]))([\.,][0-9]+)?([eE]-?\d+)?))$/; return (RE.test(input)); }
To check if a variable contains a valid number and not just a String which looks like a number, Number.isFinite(value) can be used. This is part of the language since ES2015 Examples: Number.isFinite(Infinity) // false Number.isFinite(NaN) // false Number.isFinite(-Infinity) // false Number.isFinite(0) // true Number.isFinite(2e64) // true Number.isFinite('0') // false Number.isFinite(null) // false
An integer value can be verified by: function isNumeric(value) { var bool = isNaN(+value)); bool = bool || (value.indexOf('.') != -1); bool = bool || (value.indexOf(",") != -1); return !bool; }; This way is easier and faster! All tests are checked!
Here's a lil bit improved version (probably the fastest way out there) that I use instead of exact jQuery's variant, I really don't know why don't they use this one: function isNumeric(val) { return !isNaN(+val) && isFinite(val); } The downside of jQuery's version is that if you pass a string with leading numerics and trailing letters like "123abc" the parseFloat | parseInt will extract the numeric fraction out and return 123, BUT, the second guard isFinite will fail it anyway. With the unary + operator it will die on the very first guard since + throws NaN for such hybrids :) A little performance yet I think a solid semantic gain.
My solution, function isNumeric(input) { var number = /^\-{0,1}(?:[0-9]+){0,1}(?:\.[0-9]+){0,1}$/i; var regex = RegExp(number); return regex.test(input) && input.length>0; } It appears to work in every situation, but I might be wrong.
I'm using simpler solution: function isNumber(num) { return parseFloat(num).toString() == num }
This should work. Some of the functions provided here are flawed, also should be faster than any other function here. function isNumeric(n) { var n2 = n; n = parseFloat(n); return (n!='NaN' && n2==n); } Explained: Create a copy of itself, then converts the number into float, then compares itself with the original number, if it is still a number, (whether integer or float) , and matches the original number, that means, it is indeed a number. It works with numeric strings as well as plain numbers. Does not work with hexadecimal numbers. Warning: use at your own risk, no guarantees.
None of the answers return false for empty strings, a fix for that... function is_numeric(n) { return (n != '' && !isNaN(parseFloat(n)) && isFinite(n)); }
function inNumeric(n){ return Number(n).toString() === n; } If n is numeric Number(n) will return the numeric value and toString() will turn it back to a string. But if n isn't numeric Number(n) will return NaN so it won't match the original n
Here's a dead-simple one (tested in Chrome, Firefox, and IE): function isNumeric(x) { return parseFloat(x) == x; } Test cases from question: console.log('trues'); console.log(isNumeric('-1')); console.log(isNumeric('-1.5')); console.log(isNumeric('0')); console.log(isNumeric('0.42')); console.log(isNumeric('.42')); console.log('falses'); console.log(isNumeric('99,999')); console.log(isNumeric('0x89f')); console.log(isNumeric('#abcdef')); console.log(isNumeric('1.2.3')); console.log(isNumeric('')); console.log(isNumeric('blah')); Some more test cases: console.log('trues'); console.log(isNumeric(0)); console.log(isNumeric(-1)); console.log(isNumeric(-500)); console.log(isNumeric(15000)); console.log(isNumeric(0.35)); console.log(isNumeric(-10.35)); console.log(isNumeric(2.534e25)); console.log(isNumeric('2.534e25')); console.log(isNumeric('52334')); console.log(isNumeric('-234')); console.log(isNumeric(Infinity)); console.log(isNumeric(-Infinity)); console.log(isNumeric('Infinity')); console.log(isNumeric('-Infinity')); console.log('falses'); console.log(isNumeric(NaN)); console.log(isNumeric({})); console.log(isNumeric([])); console.log(isNumeric('')); console.log(isNumeric('one')); console.log(isNumeric(true)); console.log(isNumeric(false)); console.log(isNumeric()); console.log(isNumeric(undefined)); console.log(isNumeric(null)); console.log(isNumeric('-234aa')); Note that it considers infinity a number.
I realize this has been answered many times, but the following is a decent candidate which can be useful in some scenarios. it should be noted that it assumes that '.42' is NOT a number, and '4.' is NOT a number, so this should be taken into account. function isDecimal(x) { return '' + x === '' + +x; } function isInteger(x) { return '' + x === '' + parseInt(x); } The isDecimal passes the following test: function testIsNumber(f) { return f('-1') && f('-1.5') && f('0') && f('0.42') && !f('.42') && !f('99,999') && !f('0x89f') && !f('#abcdef') && !f('1.2.3') && !f('') && !f('blah'); } The idea here is that every number or integer has one "canonical" string representation, and every non-canonical representation should be rejected. So we cast to a number and back, and see if the result is the original string. Whether these functions are useful for you depends on the use case. One feature is that distinct strings represent distinct numbers (if both pass the isNumber() test). This is relevant e.g. for numbers as object property names. var obj = {}; obj['4'] = 'canonical 4'; obj['04'] = 'alias of 4'; obj[4]; // prints 'canonical 4' to the console.
knockoutJs Inbuild library validation functions By extending it the field get validated 1) number self.number = ko.observable(numberValue).extend({ number: true}); TestCase numberValue = '0.0' --> true numberValue = '0' --> true numberValue = '25' --> true numberValue = '-1' --> true numberValue = '-3.5' --> true numberValue = '11.112' --> true numberValue = '0x89f' --> false numberValue = '' --> false numberValue = 'sfsd' --> false numberValue = 'dg##$' --> false 2) digit self.number = ko.observable(numberValue).extend({ digit: true}); TestCase numberValue = '0' --> true numberValue = '25' --> true numberValue = '0.0' --> false numberValue = '-1' --> false numberValue = '-3.5' --> false numberValue = '11.112' --> false numberValue = '0x89f' --> false numberValue = '' --> false numberValue = 'sfsd' --> false numberValue = 'dg##$' --> false 3) min and max self.number = ko.observable(numberValue).extend({ min: 5}).extend({ max: 10}); This field accept value between 5 and 10 only TestCase numberValue = '5' --> true numberValue = '6' --> true numberValue = '6.5' --> true numberValue = '9' --> true numberValue = '11' --> false numberValue = '0' --> false numberValue = '' --> false
If you need to validate a special set of decimals y you can use this simple javascript: http://codesheet.org/codesheet/x1kI7hAD <input type="text" name="date" value="" pattern="[0-9]){1,2}(\.){1}([0-9]){2}" maxlength="6" placeholder="od npr.: 16.06" onchange="date(this);" /> The Javascript: function date(inputField) { var isValid = /^([0-9]){1,2}(\.){1}([0-9]){2}$/.test(inputField.value); if (isValid) { inputField.style.backgroundColor = '#bfa'; } else { inputField.style.backgroundColor = '#fba'; } return isValid; }