在JavaScript中验证十进制数字-IsNumery()

在JavaScript中验证十进制数的最干净、最有效的方法是什么?

奖励积分:

  1. 清晰度。解决方案应该简单明了。
  2. 跨平台。

测试用例:

01. IsNumeric('-1')      => true02. IsNumeric('-1.5')    => true03. IsNumeric('0')       => true04. IsNumeric('0.42')    => true05. IsNumeric('.42')     => true06. IsNumeric('99,999')  => false07. IsNumeric('0x89f')   => false08. IsNumeric('#abcdef') => false09. IsNumeric('1.2.3')   => false10. IsNumeric('')        => false11. IsNumeric('blah')    => false
1556124 次浏览

这种方式似乎运作良好:

function IsNumeric(input){var RE = /^-{0,1}\d*\.{0,1}\d+$/;return (RE.test(input));}

在一行:

const IsNumeric = (num) => /^-{0,1}\d*\.{0,1}\d+$/.test(num);

并测试它:

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

要添加的几个测试:

IsNumeric('01.05') => falseIsNumeric('1.') => falseIsNumeric('.') => false

我想到了这个:

function IsNumeric(input) {return /^-?(0|[1-9]\d*|(?=\.))(\.\d+)?$/.test(input);}

解决方案包括:

  • 开头的可选负号
  • 一个零,或一个或多个不以0开头的数字,或只要后面有句点就什么都没有
  • 后跟1个或多个数字的句点

我想补充以下内容:

1. IsNumeric('0x89f') => true2. IsNumeric('075') => true

正十六进制数以0x开头,负十六进制数以-0x开头。正oct数以0开头,负oct数以-0开头。这个考虑了已经提到的大部分内容,但包括十六进制和八进制数,负科学,无穷大,并删除了十进制科学(4e3.2无效)。

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

使用函数isNaN。我相信如果您测试!isNaN(yourstringhere),它可以在任何这些情况下正常工作。

是的,内置的#0将比任何正则表达式解析快得多,因为它是内置和编译的,而不是动态解释的。

虽然结果与您正在寻找的结果略有不同(试试看):

                                              // IS NUMERICdocument.write(!isNaN('-1') + "<br />");      // truedocument.write(!isNaN('-1.5') + "<br />");    // truedocument.write(!isNaN('0') + "<br />");       // truedocument.write(!isNaN('0.42') + "<br />");    // truedocument.write(!isNaN('.42') + "<br />");     // truedocument.write(!isNaN('99,999') + "<br />");  // falsedocument.write(!isNaN('0x89f') + "<br />");   // truedocument.write(!isNaN('#abcdef') + "<br />"); // falsedocument.write(!isNaN('1.2.3') + "<br />");   // falsedocument.write(!isNaN('') + "<br />");        // truedocument.write(!isNaN('blah') + "<br />");    // false

它可以在没有RegExp的情况下完成

function IsNumeric(data){return parseFloat(data)==data;}

啊!不要听正则表达式的答案。RegEx对此很讨厌,我说的不仅仅是性能。用你的正则表达式很容易做出微妙的、不可能发现的错误。

如果你不能使用isNaN(),这应该工作得更好:

function IsNumeric(input){return (input - 0) == input && (''+input).trim().length > 0;}

以下是它的工作原理:

(input - 0)表达式强制JavaScript对您的输入值进行类型强制转换;减法操作必须首先将其解释为数字。如果转换为数字失败,表达式将导致NaN。然后将此数字结果与您传入的原始值进行比较。由于左侧现在是数字,因此再次使用类型强制转换。现在双方的输入都是从相同的原始值强制转换为相同的类型,您会认为它们应该始终相同(始终为真)。但是,有一个特殊的规则说NaN永远不会等于NaN,因此无法转换为数字的值(只有无法转换为数字的值)将导致false。

对长度的检查是针对涉及空字符串的特殊情况。还要注意,它落在你的0x89f测试中,但那是因为在许多环境中,这是定义数字文字的好方法。如果你想捕获那个特定的场景,你可以添加一个额外的检查。更好的是,如果这是你不使用isNaN()的原因,那么只需将你自己的函数包装在isNaN()周围,它也可以进行额外的检查。

简而言之,如果你想知道一个值是否可以转换为一个数字,实际上尝试将其转换为一个数字。


我回去为为什么做了一些研究,一个空白字符串没有预期的输出,我想我现在明白了:一个空字符串被强制为0而不是NaN。在长度检查之前简单地修剪字符串就可以处理这种情况。

对新代码运行单元测试,它只在无穷大和布尔文字上失败,唯一应该有问题的时间是如果你正在生成代码(真的,谁会输入文字并检查它是否是数字?你应该知道),这将是一些奇怪的代码。

再一次,使用它的唯一原因是,由于某种原因,您必须避免使用isNaN()。

雅虎!UI使用这个:

isNumber: function(o) {return typeof o === 'number' && isFinite(o);}
function IsNumeric(num) {return (num >=0 || num < 0);}

这也适用于0x23类型数字。

@Joel的回答非常接近,但在以下情况下会失败:

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

前段时间,我不得不实现一个IsNumeric函数,找出一个变量是否包含一个数值,无论其类型,它可能是一个String包含一个数值(我还必须考虑指数符号等),一个Number对象,几乎任何东西都可以传递给那个函数,我不能做任何类型假设,照顾类型强制转换(例如+true == 1;,但true不应该被视为"numeric")。

我认为值得分享这组+30个单元测试用于许多函数实现,并分享通过我所有测试的一个:

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

由于强制类型转换为数字,P. S.isNaNisFinite的行为令人困惑。在ES6中,Number.isNaNNumber.is有限将解决这些问题。使用它们时请记住这一点。


更新这是jQuery现在如何做到这一点(2.2稳定)

#请求参数
isNumeric: function(obj) {var realStringObj = obj && obj.toString();return !jQuery.isArray(obj) && (realStringObj - parseFloat(realStringObj) + 1) >= 0;}

更新Angular 4.3

#请求参数
export function isNumeric(value: any): boolean {return !isNaN(value - parseFloat(value));}

对我来说,这是最好的方法:

isNumber : function(v){return typeof v === 'number' && isFinite(v);}

这应该可以工作。这里提供的一些功能是有缺陷的,也应该比这里的任何其他功能更快。

        function isNumeric(n){var n2 = n;n = parseFloat(n);return (n!='NaN' && n2==n);}

解释:

创建自己的副本,然后将数字转换为浮点数,然后将自己与原始数字进行比较,如果它仍然是一个数字(无论是整数还是浮点数),并与原始数字相匹配,这意味着它确实是一个数字。

它适用于数字字符串和普通数字。不适用于十六进制数字。

警告:使用风险自负,没有保证。

以下方法也可能奏效。

function isNumeric(v) {return v.length > 0 && !isNaN(v) && v.search(/[A-Z]|[#]/ig) == -1;};
return (input - 0) == input && input.length > 0;

对我不起作用。当我输入警报并进行测试时,input.lengthundefined。我认为没有属性可以检查整数长度。所以我所做的是

var temp = '' + input;return (input - 0) == input && temp.length > 0;

它工作得很好。

我的解决方案,

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

它似乎在任何情况下都有效,但我可能错了。

整数值可以通过以下方式验证:

function isNumeric(value) {var bool = isNaN(+value));bool = bool || (value.indexOf('.') != -1);bool = bool || (value.indexOf(",") != -1);return !bool;};

这种方式更容易和更快!所有的测试都检查!

@Zoltan Lengyel'其他语言环境'评论(4月26日2:14)在@CMS 12月回答(2'09 at 5:36):

我建议测试typeof (n) === 'string'

    function isNumber(n) {if (typeof (n) === 'string') {n = n.replace(/,/, ".");}return !isNaN(parseFloat(n)) && isFinite(n);}

这扩展了Zoltans的建议,不仅能够测试像isNumber('12,50')这样的“本地化数字”,还可以测试像isNumber(2011)这样的“纯”数字。

我用我做的这个…

到目前为止,它一直在工作:

function checkNumber(value) {if ( value % 1 == 0 )return true;elsereturn false;}

如果你发现任何问题,请告诉我。

就像任何数字都应该可以被一整除而没有任何剩余一样,我想我可以使用模块,如果你尝试将字符串分成一个数字,结果就不会是这样。所以。

如果我没弄错的话,这应该匹配任何有效的JavaScript数字值,不包括常量(InfinityNaN)和符号运算符+/-(因为就我而言,它们实际上不是数字的一部分,它们是单独的运算符):

我需要这个标记器,将数字发送到JavaScript进行评估不是一个选择……它绝对不是最短的正则表达式,但我相信它捕捉到了JavaScript数字语法的所有细微之处。

/^(?:(?:(?:[1-9]\d*|\d)\.\d*|(?:[1-9]\d*|\d)?\.\d+|(?:[1-9]\d*|\d))(?:[e]\d+)?|0[0-7]+|0x[0-9a-f]+)$/i

有效数字包括:

 - 0- 00- 01- 10- 0e1- 0e01- .0- 0.- .0e1- 0.e1- 0.e00- 0xf- 0Xf

无效的数字将是

 - 00e1- 01e1- 00.0- 00x0- .- .e0

我使用更简单的解决方案:

function isNumber(num) {return parseFloat(num).toString() == num}

在这里,我从这个页面收集了“好的”,并将它们放入一个简单的测试模式中,供您自行评估。

对于新手来说,console.log是一个内置函数(在所有现代浏览器中都可用),它可以让你将结果输出到JavaScript控制台(四处挖掘,你会找到它),而不必输出到你的超文本标记语言页面。

var isNumeric = function(val){// --------------------------// Recommended// --------------------------
// jQuery - works rather well// See CMS's unit test also: http://dl.getdropbox.com/u/35146/js/tests/isNumber.htmlreturn !isNaN(parseFloat(val)) && isFinite(val);
// Aquatic - good and fast, fails the "0x89f" test, but that test is questionable.//return parseFloat(val)==val;
// --------------------------// Other quirky options// --------------------------// Fails on "", null, newline, tab negative.//return !isNaN(val);
// user532188 - fails on "0x89f"//var n2 = val;//val = parseFloat(val);//return (val!='NaN' && n2==val);
// Rafael - fails on negative + decimal numbers, may be good for isInt()?// return ( val % 1 == 0 ) ? true : false;
// pottedmeat - good, but fails on stringy numbers, which may be a good thing for some folks?//return /^-?(0|[1-9]\d*|(?=\.))(\.\d+)?$/.test(val);
// Haren - passes all// borrowed from http://www.codetoad.com/javascript/isnumeric.asp//var RE = /^-{0,1}\d*\.{0,1}\d+$/;//return RE.test(val);
// YUI - good for strict adherance to number type. Doesn't let stringy numbers through.//return typeof val === 'number' && isFinite(val);
// user189277 - fails on "" and "\n"//return ( val >=0 || val < 0);}
var tests = [0, 1, "0", 0x0, 0x000, "0000", "0x89f", 8e5, 0x23, -0, 0.0, "1.0", 1.0, -1.5, 0.42, '075', "01", '-01', "0.", ".0", "a", "a2", true, false, "#000", '1.2.3', '#abcdef', '', "", "\n", "\t", '-', null, undefined];
for (var i=0; i<tests.length; i++){console.log( "test " + i + ":    " + tests[i] + "    \t   " + isNumeric(tests[i]) );}

从jQuery 1.7开始,您可以使用#0

$.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

请注意,与你所说的不同,0x89f是一个有效的数字(十六进制)

接受的答案没有通过你的测试7,我想这是因为你改变了主意。所以这是对接受的答案的回应,我有问题。

在一些项目中,我需要验证一些数据,并尽可能确定它是一个可用于数学运算的javascript数值。

jQuery和其他一些javascript库已经包含了这样一个函数,通常称为isNumeric。还有一个stackoverflow上的帖子已被广泛接受为答案,与上述库使用的通用例程相同。

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

首先,如果参数是长度为1的数组,并且该元素的类型被上述逻辑视为数字,则上面的代码将返回true。在我看来,如果它是一个数组,那么它不是数字。

为了缓解这个问题,我从逻辑中添加了一个检查来折扣数组

function isNumber(n) {return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n);}

当然,您也可以使用Array.isArray、jQuery$.isArray或原型Object.isArray而不是Object.prototype.toString.call(n) !== '[object Array]'

我的第二个问题是负十六进制整数文字字符串(“-0xA”->-10)不被算作数字。但是,正十六进制整数文字字符串(“0xA”->10)被视为数字。我需要两者都是有效的数字。

然后我修改了逻辑以考虑到这一点。

function isNumber(n) {return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));}

如果你担心每次调用函数时创建正则表达式,那么你可以在闭包中重写它,类似这样

var isNumber = (function () {var rx = /^-/;
return function (n) {return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(rx, ''));};}());

然后我拿了CMS+30个测试用例并克隆了在jsfiddle上测试,添加了我的额外测试用例和我上面描述的解决方案。

它可能不会取代广泛接受/使用的答案,但如果这更像您期望的isNumery函数的结果,那么希望这将有所帮助。

编辑:正如Bergi所指出的,还有其他可能的对象可以被视为数字,最好是白名单而不是黑名单。考虑到这一点,我将添加到标准中。

我希望我的isNumera函数只考虑数字或字符串

考虑到这一点,最好使用

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(/^-/, ''));}

测试解决方案

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 resultsisNumber = functionsToTest[functionNumber]; // Override the isNumber global function with the one to testtestSuite(); // Run the test
// Get test resultsvar 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>

KnockoutJs Inbuild库验证函数

通过扩展它,字段得到验证

1)数量

self.number = ko.observable(numberValue).扩展({数字:true})

测试用例

numberValue = '0.0'    --> truenumberValue = '0'      --> truenumberValue = '25'     --> truenumberValue = '-1'     --> truenumberValue = '-3.5'   --> truenumberValue = '11.112' --> truenumberValue = '0x89f'  --> falsenumberValue = ''       --> falsenumberValue = 'sfsd'   --> falsenumberValue = 'dg##$'  --> false

2)数字

self.number = ko.observable(numberValue).扩展({digit: true})

测试用例

numberValue = '0'      --> truenumberValue = '25'     --> truenumberValue = '0.0'    --> falsenumberValue = '-1'     --> falsenumberValue = '-3.5'   --> falsenumberValue = '11.112' --> falsenumberValue = '0x89f'  --> falsenumberValue = ''       --> falsenumberValue = 'sfsd'   --> falsenumberValue = 'dg##$'  --> false

3)min和max

self.number = ko.observable(numberValue).扩展({min: 5}).扩展({max: 10})

此字段仅接受5到10之间的值

测试用例

numberValue = '5'    --> truenumberValue = '6'    --> truenumberValue = '6.5'  --> truenumberValue = '9'    --> truenumberValue = '11'   --> falsenumberValue = '0'    --> falsenumberValue = ''    --> false

@陈志立:您的代码片段在我的机器上使用nodejs的空格情况下失败。所以我将其与@乔尔的回答到以下:

is_float = function(v) {return !isNaN(v) && isFinite(v) &&(typeof(v) == 'number' || v.replace(/^\s+|\s+$/g, '').length > 0);}

我用那些浮点数的情况对其进行了统一测试:

var t = [0,1.2123,'0','2123.4',-1,'-1',-123.423,'-123.432',07,0xad,'07','0xad'];

以及那些没有浮点数的情况(包括空空格和对象/数组):

    var t = ['hallo',[],{},'jklsd0','',"\t","\n",' '];

这里一切正常。也许这有帮助。

可以找到完整的源代码这里

这是我使用的一个小改进版本(可能是最快的方法),而不是精确的jQuery变体,我真的不知道他们为什么不使用这个:

function isNumeric(val) {return !isNaN(+val) && isFinite(val);}

jQuery版本的缺点是,如果你传递一个带有前导数字和尾随字母的字符串,如"123abc"parseFloat | parseInt将提取数字小数并返回123,但是,第二个保护isFinite无论如何都会失败。使用一元+运算符,它将在第一个守卫上死亡,因为+为这种混合体抛出NaN:)一个小性能,但我认为一个坚实的语义增益。

我在@CMS的回答中遇到的唯一问题是排除了NaN和Infinity,它们在许多情况下都是有用的数字。检查NaN的一种方法是检查不等于自己的数值,NaN != NaN!所以你真的想处理3个测试…

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')falseisFiniteNumber('OxFF')trueisNumber('NaN')trueisNumber(1/0-1/0)trueisComparableNumber('NaN')falseisComparableNumber('Infinity')true

我的is比较数字非常接近另一个优雅的回答,但处理十六进制和其他数字的字符串表示。

我找到了简单的解决方案,可能不是最好的,但它工作得很好:)

所以,接下来我要做的是,我将字符串解析为Int并检查新变量的长度大小(现在是int类型)是否与原始字符串变量的长度相同。从逻辑上讲,如果大小相同,则意味着字符串完全解析为int,只有当字符串仅由数字“制成”时才可能。

var val=1+$(e).val()+'';var n=parseInt(val)+'';if(val.length == n.length )alert('Is int');

您可以轻松地将该代码放入函数中,而不是警报,如果使用int则返回true。请记住,如果您在字符串中使用点或逗号,您将检查它是否仍然为假,因为您正在解析为int。

注意:在e.val上添加1+,因此不会删除起始零。

我已经运行了下面的代码,它通过了所有的测试用例…

它利用了parseFloatNumber处理输入的不同方式。

function IsNumeric(_in) {return (parseFloat(_in) === Number(_in) && Number(_in) !== NaN);}

以下内容似乎适用于许多情况:

function isNumeric(num) {return (num > 0 || num === 0 || num === '0' || num < 0) && num !== true && isFinite(num);}

这是建立在这个答案之上的(也适用于这个答案):https://stackoverflow.com/a/1561597/1985601

我意识到最初的问题没有提到jQuery,但如果你确实使用jQuery,你可以这样做:

$.isNumeric(val)

简单。

https://api.jquery.com/jQuery.isNumeric/(从jQuery 1.7开始)

我知道这个问题已经回答了很多次,但以下是一个不错的候选者,在某些情况下可能有用。

应该注意的是,它假设'.42'不是一个数字,'4.'不是一个数字,因此应该考虑到这一点。

function isDecimal(x) {return '' + x === '' + +x;}
function isInteger(x) {return '' + x === '' + parseInt(x);}

isDecimal通过以下测试:

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

这里的想法是,每个数字或整数都有一个“规范”的字符串表示,每个非规范的表示都应该被拒绝。所以我们转换为一个数字并返回,看看结果是否是原始字符串。

这些函数是否对您有用取决于用例。一个特性是不同的字符串代表不同的数字(如果两者都通过isNumber()测试)。

这是相关的,例如,作为对象属性名称的数字。

var obj = {};obj['4'] = 'canonical 4';obj['04'] = 'alias of 4';obj[4];  // prints 'canonical 4' to the console.

我使用这种方式来处理变量是数字的:

v * 1 == v
function isNumber(n) {return (n===n+''||n===n-0) && n*0==0 && /\S/.test(n);}

解释:

(n===n-0||n===n+'')验证n是数字还是字符串(丢弃数组,布尔值,日期,空,…)。您可以将(n===n-0||n===n+'')替换为n!==undefined && n!==null && (n.constructor===Number||n.constructor===String):速度明显更快但不那么简洁。

n*0==0isFinite(n)一样验证n是否为有限数。如果您需要检查表示负十六进制的字符串,只需将n*0==0替换为类似n.toString().replace(/^\s*-/,'')*0==0的内容。
当然,它的成本有点高,所以如果你不需要它,不要使用它。

/\S/.test(n)丢弃仅包含空格(因为#1在这种情况下返回#2正)的空字符串或字符串。您可以通过使用(n!=0||/0/.test(n))而不是/\S/.test(n)将调用次数减少到.test(n),或者您可以使用稍微更快但不太简洁的测试,例如(n!=0||(n+'').indexOf('0')>=0):微小改进。

对于空字符串,没有一个答案返回false,这是一个修复…

function is_numeric(n){return (n != '' && !isNaN(parseFloat(n)) && isFinite(n));}

可以使用像https://github.com/arasatasaygin/is.js这样的类型检查库,或者从那里提取一个检查片段(https://github.com/arasatasaygin/is.js/blob/master/is.js#L131):

is.nan = function(value) {    // NaN is number :)return value !== value;};// is a given value number?is.number = function(value) {return !is.nan(value) && Object.prototype.toString.call(value) === '[object Number]';};

一般来说,如果您需要它来验证参数类型(在函数调用的切入点上),您可以使用符合JSDOC的合约(https://www.npmjs.com/package/bycontract):

/*** This is JSDOC syntax* @param {number|string} sum* @param {Object.<string, string>} payload* @param {function} cb*/function foo( sum, payload, cb ) {// Test if the contract is respected at entry pointbyContract( arguments, [ "number|string", "Object.<string, string>", "function" ] );}// Test itfoo( 100, { foo: "foo" }, function(){}); // okfoo( 100, { foo: 100 }, function(){}); // exception

如果您需要验证一组特殊的小数y您可以使用这个简单的javascript:

<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);" />

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

isNumeric=(el)=>{return Boolean(parseFloat(el)) && isFinite(el)}

没有什么不同,但我们可以使用布尔构造函数

检查变量是否包含有效数字,而不是只是一个看起来像数字的字符串,Number.isFinite(value)可以使用。

这是语言的一部分,因为ES2015

示例:

Number.isFinite(Infinity)   // falseNumber.isFinite(NaN)        // falseNumber.isFinite(-Infinity)  // false
Number.isFinite(0)          // trueNumber.isFinite(2e64)       // true
Number.isFinite('0')        // falseNumber.isFinite(null)       // false
function isNumeric(n) {var isNumber = true;
$.each(n.replace(/ /g,'').toString(), function(i, v){if(v!=',' && v!='.' && v!='-'){if(isNaN(v)){isNumber = false;return false;}}});
return isNumber;}
isNumeric(-3,4567.89);   // true <br>
isNumeric(3,4567.89);   // true <br>
isNumeric("-3,4567.89");   // true <br>
isNumeric(3d,4567.89);   // false

最好的方法是这样做:

function isThisActuallyANumber(data){return ( typeof data === "number" && !isNaN(data) );}

我认为parseFloat函数可以在这里完成所有工作。下面的函数通过了此页面上的所有测试,包括isNumeric(Infinity) == true

function isNumeric(n) {
return parseFloat(n) == n;}
function inNumeric(n){return Number(n).toString() === n;}

如果n是数字,Number(n)将返回数值,toString()将其转换回字符串。但如果n不是数字,Number(n)将返回NaN,因此它与原始n不匹配

我认为我的代码是完美的…

/*** @param {string} s* @return {boolean}*/var isNumber = function(s) {return s.trim()!=="" && !isNaN(Number(s));};

$('.rsval').bind('keypress', function(e){var asciiCodeOfNumbers = [48,46, 49, 50, 51, 52, 53, 54, 54, 55, 56, 57];var keynum = (!window.event) ? e.which : e.keyCode;var splitn = this.value.split(".");var decimal = splitn.length;var precision = splitn[1];if(decimal == 2 && precision.length >= 2  ) { console.log(precision , 'e');   e.preventDefault(); }if( keynum == 46 ){if(decimal > 2) { e.preventDefault(); }}if ($.inArray(keynum, asciiCodeOfNumbers) == -1)e.preventDefault();});

您可以通过多种方式最小化此函数,也可以使用负值或自定义图表的自定义正则表达式来实现它:

$('.number').on('input',function(){var n=$(this).val().replace(/ /g,'').replace(/\D/g,'');if (!$.isNumeric(n))$(this).val(n.slice(0, -1))else$(this).val(n)});

不需要使用额外的lib。

const IsNumeric = (...numbers) => {return numbers.reduce((pre, cur) => pre && !!(cur === 0 || +cur), true);};

测试

> IsNumeric(1)true> IsNumeric(1,2,3)true> IsNumeric(1,2,3,0)true> IsNumeric(1,2,3,0,'')false> IsNumeric(1,2,3,0,'2')true> IsNumeric(1,2,3,0,'200')true> IsNumeric(1,2,3,0,'-200')true> IsNumeric(1,2,3,0,'-200','.32')true

通过利用语言的动态类型检查的简单而干净的解决方案:

function IsNumeric (string) {if(string === ' '.repeat(string.length)){return false}return string - 0 === string * 1}

如果你不关心空白,你可以删除“如果”

请参阅下面的测试案例

function IsNumeric (string) {if(string === ' '.repeat(string.length)){return false}return string - 0 === string * 1}

console.log('-1' + ' → ' + IsNumeric('-1'))console.log('-1.5' + ' → ' + IsNumeric('-1.5'))console.log('0' + ' → ' + IsNumeric('0'))console.log('0.42' + ' → ' + IsNumeric('0.42'))console.log('.42' + ' → ' + IsNumeric('.42'))console.log('99,999' + ' → ' + IsNumeric('99,999'))console.log('0x89f' + ' → ' + IsNumeric('0x89f'))console.log('#abcdef' + ' → ' + IsNumeric('#abcdef'))console.log('1.2.3' + ' → ' + IsNumeric('1.2.3'))console.log('' + ' → ' + IsNumeric(''))console.log('33 ' + ' → ' + IsNumeric('33 '))

这是一个非常简单(在Chrome、Firefox和IE中测试过):

function isNumeric(x) {return parseFloat(x) == x;}

来自问题的测试用例:

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'));

更多测试用例:

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'));

请注意,它认为无穷大是一个数字。

使用regex,我们可以涵盖问题中提出的所有情况。这里是:

对于所有整数和小数都是数字:

const isNumeric = num => /^-?[0-9]+(?:\.[0-9]+)?$/.test(num+'');

仅表示整数的整数:

const isInteger = num => /^-?[0-9]+$/.test(num+'');

如果typeof n === 'string',需要检查空/未定义条件并删除逗号(对于美国数字格式)。

function isNumeric(n){if(n === null || typeof n === 'undefined')return false;
if(typeof n === 'string')n = n.split(',').join('');
return !isNaN(parseFloat(n)) && isFinite(n);}

https://jsfiddle.net/NickU/nyzeot03/3/

如果您希望数字函数谓词隐式严格(例如,不解析字符串),那么这应该可以解决问题。

function isNumeric(n, parse) {var t = typeof(n);if (parse){if (t !== 'number' && t !=='string') return false;return !isNaN(parseFloat(n)) && isFinite(n);}else{if (t !== 'number') return false;return !isNaN(n) && isFinite(n) && !_.isString(n);}}
function isInteger(n, parse) {return isNumeric(n, parse) && n % 1 === 0;}
function isFloat(n, parse) {return isNumeric(n, parse) && n % 1 !== 0;}

如果您希望代码解析字符串,那么只需在parse参数中传递true即可。

这是对underscore-contrib方法的修改,它是隐式松散的,尝试解析字符串,甚至为isNumeric([1])返回true,这对人们来说可能是一个真正的陷阱。我上面的方法也会更快,因为它只在parse=true时调用parseFloat()