Validate decimal numbers in JavaScript - IsNumeric()
在javascript中验证十进制数字最干净、最有效的方法是什么?
奖励积分:
测试用例:
1 2 3 4 5 6 7 8 9 10 11 | 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 |
@乔尔的回答非常接近,但在以下情况下会失败:
1 2 3 4 5 6 7 8 9 10 11 12 | // Whitespace strings: IsNumeric(' ') == true; IsNumeric('\t\t') == true; IsNumeric(' ') == true; // Number literals: IsNumeric(-1) == false; IsNumeric(0) == false; IsNumeric(1.1) == false; IsNumeric(8e5) == false; |
一段时间以前,我必须实现一个
我认为值得分享这组对许多函数实现所做的+30单元测试,也值得分享通过我所有测试的测试:
1 2 3 | function isNumeric(n) { return !isNaN(parseFloat(n)) && isFinite(n); } |
由于强制转换为数字,P.S.isnan&isfemit具有令人困惑的行为。在ES6中,number.isnan&number.isfemited将解决这些问题。使用时请记住这一点。
更新:下面是jquery现在的工作方式(2.2-stable):
1 2 3 4 | isNumeric: function(obj) { var realStringObj = obj && obj.toString(); return !jQuery.isArray(obj) && (realStringObj - parseFloat(realStringObj) + 1) >= 0; } |
更新:角度4.3:
1 2 3 | export function isNumeric(value: any): boolean { return !isNaN(value - parseFloat(value)); } |
哎呀!不要听正则表达式的答案。雷杰克斯对此很讨厌,我说的不仅仅是表演。用正则表达式很容易做出细微的、不可能发现错误的错误。
如果您不能使用
1 2 3 4 | function IsNumeric(input) { return (input - 0) == input && (''+input).trim().length > 0; } |
它的工作原理如下:
对长度的检查适用于涉及空字符串的特殊情况。还要注意,它落在了您的0x89F测试上,但这是因为在许多环境中,这是定义数字文本的一种好方法。如果您想要捕捉那个特定的场景,可以添加一个额外的检查。更好的是,如果这是您不使用
总之,如果您想知道某个值是否可以转换为数字,请尝试将其转换为数字。
我回去做了一些研究,为什么空白字符串没有预期的输出,我想我现在明白了:空字符串被强制到
运行针对新代码的单元测试,它只会在无穷大和布尔文本上失败,唯一应该出现问题的时间是是否正在生成代码(实际上,谁会输入文本并检查它是否是数字的)?您应该知道),这将是一些要生成的奇怪代码。
但是,同样,使用它的唯一原因是,出于某种原因,必须避免isan()。
这种方法似乎很有效:
1 2 3 4 | function IsNumeric(input){ var RE = /^-{0,1}\d*\.{0,1}\d+$/; return (RE.test(input)); } |
并测试它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // alert(TestIsNumeric()); function TestIsNumeric(){ var results = '' results += (IsNumeric('-1')?"Pass":"Fail") +": IsNumeric('-1') => true "; results += (IsNumeric('-1.5')?"Pass":"Fail") +": IsNumeric('-1.5') => true "; results += (IsNumeric('0')?"Pass":"Fail") +": IsNumeric('0') => true "; results += (IsNumeric('0.42')?"Pass":"Fail") +": IsNumeric('0.42') => true "; results += (IsNumeric('.42')?"Pass":"Fail") +": IsNumeric('.42') => true "; results += (!IsNumeric('99,999')?"Pass":"Fail") +": IsNumeric('99,999') => false "; results += (!IsNumeric('0x89f')?"Pass":"Fail") +": IsNumeric('0x89f') => false "; results += (!IsNumeric('#abcdef')?"Pass":"Fail") +": IsNumeric('#abcdef') => false "; results += (!IsNumeric('1.2.3')?"Pass":"Fail") +": IsNumeric('1.2.3') => false "; results += (!IsNumeric('')?"Pass":"Fail") +": IsNumeric('') => false "; results += (!IsNumeric('blah')?"Pass":"Fail") +": IsNumeric('blah') => false "; return results; } |
我从http://www.codetoad.com/javascript/isnumeric.asp借用了这个regex。说明:
1 2 3 4 5 6 | /^ 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 |
雅虎!UI使用:
1 2 3 | isNumber: function(o) { return typeof o === 'number' && isFinite(o); } |
1 2 3 | function IsNumeric(num) { return (num >=0 || num < 0); } |
这也适用于0x23类型的数字。
被接受的答案没有通过你的测试,我猜是因为你改变了主意。所以这是对公认答案的回应,我对此有异议。
在一些项目中,我需要验证一些数据,并尽可能确定它是一个可用于数学运算的javascript数值。
jquery和其他一些javascript库已经包含了这样一个函数,通常称为
1 2 3 | function isNumber(n) { return !isNaN(parseFloat(n)) && isFinite(n); } |
首先,如果参数是长度为1的数组,并且单个元素的类型被上述逻辑视为数字,那么上面的代码将返回true。在我看来,如果它是一个数组,那么它不是数字。
为了解决这个问题,我从逻辑中向折扣数组添加了一个检查
1 2 3 | function isNumber(n) { return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n); } |
当然,也可以使用
我的第二个问题是,负十六进制整型文本字符串("-0xa"->-10)没有被计算为数字。但是,正十六进制整数文本字符串("0xA"->10)被视为数字。我需要两者都是有效的数字。
然后我修改了逻辑以考虑到这一点。
1 2 3 | function isNumber(n) { return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, '')); } |
如果您担心每次调用函数时都会创建regex,那么您可以在一个闭包中重写它,类似于这样
1 2 3 4 5 6 7 | var isNumber = (function () { var rx = /^-/; return function (n) { return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(rx, '')); }; }()); |
然后我取了CMSS+30测试用例,在jsFiddle上克隆了测试,添加了我的额外测试用例和我上面描述的解决方案。
它可能无法取代广为接受/使用的答案,但如果这更多的是您期望的结果,从您的isNumeric函数,那么希望这将是一些帮助。
编辑:正如Bergi所指出的,还有其他可能被认为是数字的对象,白名单比黑名单更好。考虑到这一点,我将增加标准。
我希望isNumeric函数只考虑数字或字符串
考虑到这一点,最好使用
1 2 3 | 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(/^-/, '')); } |
测试解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | 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()); }); }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"> <script src="https://rawgit.com/Xotic750/testrunner-old/master/testrunner.js" type="text/javascript"> <link href="https://rawgit.com/Xotic750/testrunner-old/master/testrunner.css" rel="stylesheet" type="text/css"> isNumber Test Cases <h2 id="banner" class="pass"> <h2 id="userAgent">Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11 <label for="toTest" style="font-weight:bold; font-size:Large;">Select function to test:</label> <select id="toTest" name="toTest"> </select> <li class="pass"> Integer Literals <b style="color:black;">(0, 10, 10) <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> </li> <li class="pass"> Foating-Point Literals <b style="color:black;">(0, 6, 6) <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> </li> <li class="pass"> Non-Numeric values <b style="color:black;">(0, 18, 18) <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> </li> This page contains tests for a set of isNumber functions. To see them, take a look at the source. <p class="result">Tests completed in 0 milliseconds. 0 tests of 0 failed. </p> |
是的,内置的
虽然结果与您要查找的结果有些不同(尝试一下):
1 2 3 4 5 6 7 8 9 10 11 12 | // 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 |
使用函数
由于jquery 1.7,可以使用
1 2 3 4 5 6 7 8 9 10 11 | $.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 |
请注意,与您所说的不同,
它可以在没有regexp as的情况下完成
1 2 3 | function IsNumeric(data){ return parseFloat(data)==data; } |
我知道原来的问题没有提到jquery,但是如果你使用jquery,你可以做到:
1 | $.isNumeric(val) |
简单。
https://api.jquery.com/jquery.isnumeric/(自jquery 1.7起)
1 | return (input - 0) == input && input.length > 0; |
不适合我。当我发出警报并进行测试时,
1 2 | var temp = '' + input; return (input - 0) == input && temp.length > 0; |
效果很好。
如果我没有弄错,这应该与任何有效的javascript数字值相匹配,不包括常量(
我需要一个标记器,在那里把数字发送到javascript进行评估不是一个选择…它绝对不是最短的正则表达式,但我相信它捕捉到了javascript数字语法的所有细微之处。
1 2 | /^(?:(?:(?:[1-9]\d*|\d)\.\d*|(?:[1-9]\d*|\d)?\.\d+|(?:[1-9]\d*|\d)) (?:[e]\d+)?|0[0-7]+|0x[0-9a-f]+)$/i |
有效数字包括:
1 2 3 4 5 6 7 8 9 10 11 12 13 | - 0 - 00 - 01 - 10 - 0e1 - 0e01 - .0 - 0. - .0e1 - 0.e1 - 0.e00 - 0xf - 0Xf |
无效的数字将是
1 2 3 4 5 6 | - 00e1 - 01e1 - 00.0 - 00x0 - . - .e0 |
对我来说,这是最好的方法:
1 2 3 | isNumber : function(v){ return typeof v === 'number' && isFinite(v); } |
对于@cms的答案,我唯一的问题是排除了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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 |
我的isComparableNumber非常接近另一个优雅的答案,但它处理十六进制和其他数字的字符串表示。
我想增加以下内容:
1 2 | <wyn>1. IsNumeric('0x89f') => true 2. IsNumeric('075') => true</wyn> |
正十六进制数以
1 2 3 4 | 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)); } |
这里有一个lil位的改进版本(可能是最快的方法),我使用它来代替jquery的精确变体,我真的不知道他们为什么不使用这个版本:
1 2 3 | function isNumeric(val) { return !isNaN(+val) && isFinite(val); } |
jquery版本的缺点是,如果传递一个带有前导数字和尾随字母的字符串(如
整数值可通过以下方式验证:
1 2 3 4 5 6 | function isNumeric(value) { var bool = isNaN(+value)); bool = bool || (value.indexOf('.') != -1); bool = bool || (value.indexOf(",") != -1); return !bool; }; |
这条路越来越容易!检查所有测试!
我的解决方案,
1 2 3 4 5 | 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; } |
它似乎在任何情况下都有效,但我可能错了。
这应该有效。这里提供的一些函数是有缺陷的,也应该比这里的任何其他函数都快。
1 2 3 4 5 6 | function isNumeric(n) { var n2 = n; n = parseFloat(n); return (n!='NaN' && n2==n); } |
解释:
创建一个自身的副本,然后将该数字转换为浮点数,然后将自身与原始数字进行比较,如果它仍然是一个数字(无论是整数还是浮点数),并与原始数字匹配,这意味着它确实是一个数字。
它适用于数字字符串和普通数字。不适用于十六进制数。
警告:请自行承担风险,不提供任何保证。
检查变量是否包含有效数字只是一个看起来像数字的字符串,可以使用
这是语言的一部分,因为ES2015
实例:
1 2 3 4 5 6 7 8 9 | 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 |
要添加的几个测试:
1 2 3 | IsNumeric('01.05') => false IsNumeric('1.') => false IsNumeric('.') => false |
我想到了这个:
1 2 3 | function IsNumeric(input) { return /^-?(0|[1-9]\d*|(?=\.))(\.\d+)?$/.test(input); } |
解决方案包括:
- 开头的可选负号
- 一个零,或者一个或多个不以0开头的数字,或者只要一个句点在后面就没有。
- 后跟一个或多个数字的句点。
没有一个答案返回空字符串的
1 2 3 4 | function is_numeric(n) { return (n != '' && !isNaN(parseFloat(n)) && isFinite(n)); } |
我正在使用更简单的解决方案:
1 2 3 | function isNumber(num) { return parseFloat(num).toString() == num } |
您可以通过许多方式最小化此函数,还可以使用自定义regex实现负值或自定义图表:
1 2 3 4 5 6 7 | $('.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) }); |
1 2 3 | function inNumeric(n){ return Number(n).toString() === n; } |
如果n是数字,
我认为parsefloat函数可以在这里完成所有的工作。下面的函数通过了本页的所有测试,包括
1 2 3 4 | function isNumeric(n) { return parseFloat(n) == n; } |
我知道这个问题已经回答了很多次了,但是下面是一个不错的候选人,在某些情况下是有用的。
应该注意的是,它假定".42"不是数字,而"4."不是数字,因此应该考虑到这一点。
1 2 3 4 5 6 7 | function isDecimal(x) { return '' + x === '' + +x; } function isInteger(x) { return '' + x === '' + parseInt(x); } |
1 2 3 4 5 | 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'); } |
这里的想法是,每个数字或整数都有一个"规范的"字符串表示,并且应该拒绝每个非规范的表示。所以我们将其转换为一个数字并返回,看看结果是否是原始字符串。
这些函数是否对您有用取决于用例。一个特点是不同的字符串代表不同的数字(如果两者都通过了
这是相关的,例如,作为对象属性名称的数字。
1 2 3 4 | var obj = {}; obj['4'] = 'canonical 4'; obj['04'] = 'alias of 4'; obj[4]; // prints 'canonical 4' to the console. |
knockoutjs内置库验证函数
通过扩展它,字段得到验证
1)数
测试用例
1 2 3 4 5 6 7 8 9 10 | 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)数字
测试用例
1 2 3 4 5 6 7 8 9 10 | 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和max
此字段仅接受5到10之间的值
测试用例
1 2 3 4 5 6 7 | numberValue = '5' --> true numberValue = '6' --> true numberValue = '6.5' --> true numberValue = '9' --> true numberValue = '11' --> false numberValue = '0' --> false numberValue = '' --> false |
您可以使用类型检查库,如https://github.com/arasasasayagin/is.js,或者从中提取检查片段(https://github.com/arasasasasayagin/is.js/blob/master/is.js_l131):
1 2 3 4 5 6 7 | 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):
1 2 3 4 5 6 7 8 9 10 11 12 13 | /** * 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 point byContract( arguments, ["number|string","Object.<string, string>","function" ] ); } // Test it foo( 100, { foo:"foo" }, function(){}); // ok foo( 100, { foo: 100 }, function(){}); // exception |
不需要使用额外的lib。
1 2 3 | const IsNumeric = (...numbers) => { return numbers.reduce((pre, cur) => pre && !!(cur === 0 || +cur), true); }; |
试验
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | > 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 |
我认为我的代码是完美的…
1 2 3 4 5 6 7 | /** * @param {string} s * @return {boolean} */ var isNumber = function(s) { return s.trim()!=="" && !isNaN(Number(s)); }; |
最好的方法如下:
1 2 3 | function isThisActuallyANumber(data){ return ( typeof data ==="number" && !isNaN(data) ); } |
没有什么不同,但是我们可以使用布尔构造函数
@CMS的答案:你的代码片段在我的机器上使用nodejs的空白案例中失败。所以我把它和@乔尔对以下问题的回答:
1 2 3 4 | is_float = function(v) { return !isNaN(v) && isFinite(v) && (typeof(v) == 'number' || v.replace(/^\s+|\s+$/g, '').length > 0); } |
我把它与那些浮动的情况结合起来进行了测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | var t = [ 0, 1.2123, '0', '2123.4', -1, '-1', -123.423, '-123.432', 07, 0xad, '07', '0xad' ]; |
以及那些没有浮动的情况(包括空空格和对象/数组):
1 2 3 4 5 6 7 8 9 10 11 | var t = [ 'hallo', [], {}, 'jklsd0', '', "\t", " ", ' ' ]; |
这里一切正常。也许这有帮助。
完整的源代码可以在这里找到。
如果需要验证一组特殊的小数y您可以使用这个简单的javascript:
http://codesheet.org/codesheet/x1ki7had
1 | <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:
1 2 3 4 5 6 7 8 9 | 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; } |
1 2 3 | function isNumber(n) { return (n===n+''||n===n-0) && n*0==0 && /\S/.test(n); } |
说明:
在许多情况下,以下内容似乎可以正常工作:
1 2 3 | function isNumeric(num) { return (num > 0 || num === 0 || num === '0' || num < 0) && num !== true && isFinite(num); } |
这是建立在这个答案之上的(也适用于这个答案):https://stackoverflow.com/a/1561597/1985601
我运行了下面的程序,它通过了所有的测试用例…
它利用了不同的方式来处理
1 2 3 | function IsNumeric(_in) { return (parseFloat(_in) === Number(_in) && Number(_in) !== NaN); } |
通过利用语言的动态类型检查,一个简单而干净的解决方案:
1 2 3 4 5 6 | function IsNumeric (string) { if(string === ' '.repeat(string.length)){ return false } return string - 0 === string * 1 } |
如果你不在乎空白,你可以删除"如果"
参见下面的测试用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 ')) |
我找到了简单的解决方案,也许不是最好的,但它工作得很好:)
接下来,我将把字符串解析为int,并检查新变量(现在是int类型)的长度大小是否与原始字符串变量的长度相同。逻辑上,如果大小相同,则意味着字符串被完全解析为int,并且只有在字符串仅由数字"构成"时才可能。
1 2 3 | var val=1+$(e).val()+''; var n=parseInt(val)+''; if(val.length == n.length )alert('Is int'); |
您可以很容易地将该代码放入函数中,而不是使用alert,而是使用return true if int。记住,如果在字符串中使用点或逗号,则检查它是否仍然为假,因为您正在解析为int。
注意:在e.val上添加1+,这样就不会删除起始零。
我用这种方式来检查变量是否为数字:
1 | v * 1 == v |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 isNumeric(3,4567.89); // true isNumeric("-3,4567.89"); // true isNumeric(3d,4567.89); // false |
1 2 3 4 5 6 7 8 9 10 11 12 13 | $('.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(); }); |
@Zoltan Lengyel在@cms dec答案中的"其他地区"评论(4月26日2:14)(2009年2月5:36):
我建议对
1 2 3 4 5 6 | function isNumber(n) { if (typeof (n) === 'string') { n = n.replace(/,/,"."); } return !isNaN(parseFloat(n)) && isFinite(n); } |
这将佐尔坦的建议扩展到不仅能够测试像
嗯,我用的是我做的这个……
到目前为止,它一直在工作:
1 2 3 4 5 6 | function checkNumber(value) { if ( value % 1 == 0 ) return true; else return false; } |
如果你发现它有什么问题,请告诉我。
就像任何数字都可以被一个整除而不剩下任何东西一样,我想我可以使用这个模块,如果你尝试将一个字符串分割成一个数字,结果就不会是这个了。所以。
以下内容也可能有效。
1 2 3 | function isNumeric(v) { return v.length > 0 && !isNaN(v) && v.search(/[A-Z]|[#]/ig) == -1; }; |
在这里,我从这个页面收集了"好的"部分,并将它们放入一个简单的测试模式中,供您自己评估。
对于新手来说,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | var isNumeric = function(val){ // -------------------------- // Recommended // -------------------------- // jQuery - works rather well // See CMS's unit test also: http://dl.getdropbox.com/u/35146/js/tests/isNumber.html return !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" " //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', '',""," ","\t", '-', null, undefined]; for (var i=0; i<tests.length; i++){ console.log("test" + i +": " + tests[i] +" \t " + isNumeric(tests[i]) ); } |