2498

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

奖励积分:

  1. 明晰。解决方案应该干净简单。
  2. 跨平台。

测试用例:

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
4

50 回答 50

2965

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

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


更新这是 jQuery 现在的做法(2.2-stable)

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

更新角 4.3

export function isNumeric(value: any): boolean {
    return !isNaN(value - parseFloat(value));
}
于 2009-12-02T05:36:22.517 回答
352

啊!不要听正则表达式的答案。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()。

于 2008-10-06T16:04:45.587 回答
83

这种方式似乎运作良好:

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

我从http://www.codetoad.com/javascript/isnumeric.asp借用了那个正则表达式。解释:

/^ 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
于 2008-08-20T14:22:56.270 回答
56

雅虎!用户界面使用这个:

isNumber: function(o) {
    return typeof o === 'number' && isFinite(o);
}
于 2009-08-14T21:07:27.377 回答
53

接受的答案未通过您的测试#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或 prototypeObject.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 上克隆了测试,添加了我的额外测试用例和我上面描述的解决方案。

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

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

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

考虑到这一点,最好使用

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

于 2013-02-23T18:25:26.517 回答
51
function IsNumeric(num) {
     return (num >=0 || num < 0);
}

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

于 2009-10-13T17:05:16.153 回答
35

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

尽管结果与您正在寻找的结果有些不同(尝试一下):

                                              // 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
于 2008-08-21T04:05:11.647 回答
20

使用功能isNaN。我相信如果你测试!isNaN(yourstringhere)它在任何这些情况下都可以正常工作。

于 2008-08-21T01:02:15.237 回答
18

从 jQuery 1.7 开始,您可以使用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

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

于 2013-02-18T09:01:43.027 回答
13

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

function IsNumeric(data){
    return parseFloat(data)==data;
}
于 2008-08-22T15:08:05.757 回答
8
return (input - 0) == input && input.length > 0;

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

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

它工作得很好。

于 2011-01-28T11:22:59.740 回答
8

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

$.isNumeric(val)

简单的。

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

于 2014-01-13T16:42:50.723 回答
7

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

isNumber : function(v){
   return typeof v === 'number' && isFinite(v);
}
于 2010-05-28T11:30:26.420 回答
7

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

我需要这个用于分词器,在这种情况下,将数字发送到 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
于 2012-06-12T08:09:25.940 回答
7

我对@CMS 的回答的唯一问题是排除NaN和 Infinity,它们在许多情况下都是有用的数字。检查NaN's 的一种方法是检查不等于自身的数值,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')
false
isFiniteNumber('OxFF')
true
isNumber('NaN')
true
isNumber(1/0-1/0)
true
isComparableNumber('NaN')
false
isComparableNumber('Infinity')
true

我的 isComparableNumber 非常接近另一个优雅的答案,但可以处理数字的十六进制和其他字符串表示形式。

于 2013-06-06T23:39:05.517 回答
6

我想添加以下内容:

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

正十六进制数以 开头0x,负十六进制数以 开头-0x。正八进制数以 开头0,负八进制数以 开头-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));
}
于 2008-08-20T15:40:28.440 回答
6

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

function isNumeric(n) {

    return parseFloat(n) == n;
}
于 2016-06-22T17:57:26.417 回答
5

添加几个测试:

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

我想出了这个:

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

解决方案涵盖:

  • 开头的可选负号
  • 单个零,或一个或多个不以 0 开头的数字,或者只要后面有句点就没有
  • 后跟 1 个或多个数字的句点
于 2008-08-20T14:53:26.883 回答
4

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

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

这种方式更简单,更快捷!所有测试都经过检查!

于 2011-06-10T12:27:23.483 回答
4

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

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

jQuery 版本的缺点是,如果您传递带有前导数字和尾随字母的字符串"123abc",如 使用一元运算符,它将在第一个守卫上死去,因为 + 为这种混合体抛出 NaN :) 有点性能,但我认为这是一个可靠的语义增益。parseFloat | parseIntisFinite+

于 2013-05-20T16:48:18.587 回答
4

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

这是自 ES2015以来语言的一部分

例子:

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
于 2016-04-10T17:53:58.470 回答
3

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

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

解释:

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

它适用于数字字符串以及纯数字。不适用于十六进制数。

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

于 2010-12-06T11:30:06.170 回答
3

我的解决方案,

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

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

于 2011-02-11T23:48:34.893 回答
3

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

function isNumber(num) {
    return parseFloat(num).toString() == num
}
于 2012-06-16T12:25:25.023 回答
3

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

function is_numeric(n)
{
 return (n != '' && !isNaN(parseFloat(n)) && isFinite(n));
}
于 2014-12-23T14:38:12.737 回答
3
function inNumeric(n){
   return Number(n).toString() === n;
}

如果 n 是数字Number(n)将返回数值toString()并将其转回字符串。但是如果 n 不是数字Number(n)将返回NaN,所以它不会匹配原来的n

于 2016-08-10T20:17:15.247 回答
2

knockoutJs Inbuild 库验证函数

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

1) 号码

self.number = ko.observable(numberValue).extend({ number: true}) ;

测试用例

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) 数字

self.number = ko.observable(numberValue).extend({ digit: true}) ;

测试用例

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) 最小值和最大值

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

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

测试用例

numberValue = '5'    --> true
numberValue = '6'    --> true
numberValue = '6.5'  --> true
numberValue = '9'    --> true
numberValue = '11'   --> false
numberValue = '0'    --> false
numberValue = ''    --> false
于 2013-02-27T03:38:47.957 回答
2

我在下面运行了以下命令,它通过了所有测试用例......

它利用不同的方式来parseFloat处理Number他们的输入......

function IsNumeric(_in) {
    return (parseFloat(_in) === Number(_in) && Number(_in) !== NaN);
}
于 2013-09-27T17:32:20.420 回答
2

我意识到这已被多次回答,但以下是一个不错的候选人,在某些情况下可能很有用。

应该注意的是,它假定“.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.
于 2014-04-13T23:28:49.960 回答
2

如果您需要验证一组特殊的小数,您可以使用这个简单的 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);" />

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;
}
于 2016-02-10T19:40:59.667 回答
2

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

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

于 2016-03-30T20:10:07.360 回答
2

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

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

于 2017-01-07T21:24:03.100 回答
2

您可以通过多种方式最小化此功能,还可以使用自定义正则表达式来实现负值或自定义图表:

$('.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)
});
于 2017-02-23T14:56:19.887 回答
2

无需使用额外的库。

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
于 2017-10-30T06:25:57.537 回答
2

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

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

如果您不关心空格,则可以删除“ if ”

请参阅下面的测试用例

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

于 2019-01-26T20:47:52.183 回答
2

这是一个非常简单的(在 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'));

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

于 2019-09-25T04:13:04.417 回答
1

@CMS 的回答:您的代码片段在我的机器上使用 nodejs 的空白案例中失败。所以我将它与 @joel对以下问题的回答结合起来:

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",
        ' '
    ];

一切都在这里按预期工作。也许这有帮助。

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

于 2013-04-14T10:14:18.900 回答
1

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

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

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

于 2013-12-20T22:01:55.647 回答
1
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==0验证 n 是否是有限数isFinite(n)。如果您需要检查表示负十六进制的字符串,只需替换n*0==0n.toString().replace(/^\s*-/,'')*0==0.
当然它会花费一点,所以如果你不需要它,就不要使用它。

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

于 2014-12-14T17:13:13.070 回答
1

可以使用像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 point
  byContract( arguments, [ "number|string", "Object.<string, string>", "function" ] );
}
// Test it
foo( 100, { foo: "foo" }, function(){}); // ok
foo( 100, { foo: 100 }, function(){}); // exception
于 2016-01-14T14:25:15.040 回答
1

最好的方法是这样的:

function isThisActuallyANumber(data){
    return ( typeof data === "number" && !isNaN(data) );
}
于 2016-05-23T06:50:20.370 回答
0

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

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

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

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

注意:在 e.val 上添加 1+,因此不会删除从零开始的内容。

于 2013-07-09T23:10:44.460 回答
0

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

isNumeric 用于所有整数和小数:

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

isInteger 仅用于整数:

const isInteger = num => /^-?[0-9]+$/.test(num+'');
于 2022-02-13T01:38:10.127 回答
-1

我用这种方式来破解这个变量是数字的:

v * 1 == v
于 2014-09-16T05:32:07.797 回答
-1
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
于 2016-05-19T18:51:27.707 回答
-1
$('.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();    
  });
于 2017-02-03T07:11:21.947 回答
-2

@Zoltan Lengyel 'other locales' 评论(4 月 26 日 2:14)在@CMS 12 月回答(2009 年 2 月 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).

于 2011-09-08T14:34:33.280 回答
-3

好吧,我正在使用我制作的这个......

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

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

如果您发现它有任何问题,请告诉我。

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

于 2012-03-19T19:00:18.807 回答
-3

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

对于新手来说,这console.log是一个内置函数(在所有现代浏览器中都可用),可让您将结果输出到 JavaScript 控制台(四处寻找,您会找到),而不必输出到 HTML 页面。

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 "\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]) );
}
于 2012-11-29T04:17:13.157 回答
-4

以下可能也有效。

function isNumeric(v) {
         return v.length > 0 && !isNaN(v) && v.search(/[A-Z]|[#]/ig) == -1;
   };
于 2011-01-12T21:41:23.297 回答