Проверка десятичных чисел в JavaScript-IsNumeric()

каков самый чистый и эффективный способ проверки десятичных чисел в 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

30 ответов


@Иоиля довольно близко, но он потерпит неудачу в следующих случаях:

// 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 содержащий числовое значение (я должен был рассмотреть также экспоненциальную нотацию и т. д.), a Number объект, практически все может быть передано этой функции, я не мог сделать никаких предположений типа, забота о типе принуждения (например. +true == 1; но true не следует рассматривать как "numeric").

Я думаю, стоит поделиться этим набором +30 unit-тестов сделано для многочисленных реализаций функций, а также поделиться тем, что проходит все мои тесты:

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

П. С. isNaN & isFinite имеют запутанное поведение из-за принудительного преобразования в число. В ES6,количество.isNaN & количество.isFinite исправит эти проблемы. Имейте это в виду при их использовании.


обновление : вот как jQuery делает это сейчас (2.2-стабильный):

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

Arrrgh! Не слушайте ответы на регулярные выражения. 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().


этот способ, кажется, работает хорошо:

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

и проверить это:

// alert(TestIsNumeric());

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

я позаимствовал это выражение из 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

Yahoo! UI использует этот:

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

function IsNumeric(num) {
     return (num >=0 || num < 0);
}

это работает и для чисел типа 0x23.


принятый ответ провалил ваш тест №7, и я думаю, это потому, что вы передумали. Так это ответ на принятый ответ, с которым у меня были проблемы.

во время некоторых проектов мне нужно было проверить некоторые данные и быть как можно более уверенным, что это числовое значение javascript, которое можно использовать в математических операциях.

jQuery и некоторые другие библиотеки javascript уже включают такую функцию, обычно называемую isNumeric. Существует также сообщение на stackoverflow это было широко принято в качестве ответа, та же самая общая процедура, которую используют вышеупомянутые библиотеки.

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

во-первых, приведенный выше код будет возвращать true, если аргументом является массив длины 1, и один элемент типа считаются числовые выше логики. На мой взгляд, если это массив, то его не числовое.

чтобы облегчить эту проблему, я добавил чек на дисконтные массивы из логика!--13-->

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

я тогда взял CMSs +30 тестов и клонировали тестирование на jsfiddle добавлены мои дополнительные тестовые случаи и мое вышеописанное решение.

он не может заменить широко принятый / используемый ответ, но если это больше того, что вы ожидаете, как результаты вашей isNumeric функции, то, надеюсь, это будет иметь некоторую помощь.

EDIT: как указал Берги, есть другие возможные объекты, которые можно считать числовыми, и было бы лучше белый список, чем черный список. Имея это в виду, я бы добавил к критериям.

я хочу, чтобы моя 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>

да, встроенный 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

начиная с 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 является допустимым числом (hexa)


использование функции isNaN. Я верю, если вы проверить на !isNaN(yourstringhere) он отлично работает в любой из этих ситуаций.


Это можно сделать без RegExp как

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

Я понимаю, что исходный вопрос не упомянул jQuery, но если вы используете jQuery, вы можете сделать:

$.isNumeric(val)

простой.

https://api.jquery.com/jQuery.isNumeric/ (по состоянию на jQuery 1.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

return (input - 0) == input && input.length > 0;

не работает для меня. Когда я ввел предупреждение и протестировал, input.length был undefined. Я думаю, что нет свойства для проверки целочисленной длины. Так что я сделал

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

Он работал нормально.


для меня это лучший способ:

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

целочисленное значение может быть проверено путем:

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

этот способ проще и быстрее! Все тесты проверены!


вот немного улучшенная версия (вероятно, самый быстрый способ), которую я использую вместо точного варианта jQuery, я действительно не знаю, почему они не используют этот:

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

недостатком версии jQuery является то, что если вы передаете строку с ведущими цифрами и конечными буквами, такими как "123abc" на parseFloat | parseInt извлечет числовую дробь и вернет 123, но, второй охранник isFinite все равно не было. С унарными + оператор он умрет на очень первый охранник с + бросает NaN для таких гибридов :) Немного производительности, но я думаю, что солидный семантический выигрыш.


единственная проблема, которую я имел с @CMS ответ исключение NaN и бесконечность, которые являются полезными числами для многих ситуаций. Один из способов проверить 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 довольно близок к другому элегантному ответ, но обрабатывает шестнадцатеричные и другие строковые представления чисел.


несколько тестов, чтобы добавить:

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

Я придумал это:

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

решение охватывает:

  • необязательный отрицательный знак в начале
  • один ноль, или одна или несколько цифр, не начинающихся с 0, или ничего, пока период следует
  • период, за которым следует 1 или более цифр

мое решение,

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(n)
        {
            var n2 = n;
            n = parseFloat(n);
            return (n!='NaN' && n2==n);
        }

пояснил:

создайте копию себя, затем преобразует число в float, затем сравнивает себя с исходным числом, если это все еще число (будь то целое число или float) , и соответствует исходному числу, это означает, что это действительно число.

Он работает с числовыми строками, а также Простые числа. Не работа с шестнадцатеричными числами.

предупреждение: используйте на свой страх и риск, никаких гарантий.


Я хотел бы добавить следующее:

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

положительные шестнадцатеричные числа начинаются с 0x и отрицательные шестнадцатеричные числа начинаются с -0x. Положительные числа oct начинаются с 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));
}

Я использую более простое решение:

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

ни один из ответов не возвращается false для пустых строк, как это исправить...

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

@CMS ' ответ: ваш фрагмент не удался в случаях пробелов на моей машине с помощью nodejs. Поэтому я объединил его с @Иоиля следующим образом:

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

Я unittested его с теми случаями, которые плавают:

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

и те случаи, которые не являются поплавками (включая пустые пробелы и объекты / массивы):

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

здесь все работает так, как ожидалось. Может, это поможет.

полный исходный код может быть найденным здесь.


Кажется, что во многих случаях отлично работает следующее:

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

это построено поверх этого ответа (который для этого ответа тоже): https://stackoverflow.com/a/1561597/1985601


Я понимаю, что на это ответили много раз, но следующий достойный кандидат, который может быть полезен в некоторых сценариях.

следует отметить, что он предполагает, что '.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');
}

идея здесь в том, что каждое число или целое число имеет одно "каноническое" строковое представление, а каждое неканоническое представление должно быть отклонено. Поэтому мы переходим к числу и обратно и видим, является ли результат исходной строкой.

полезны ли эти функции для вас, зависит от варианта использования. Одной из особенностей является то, что отдельные строки представляют различные числа (если оба передают


knockoutJs встроенные функции проверки библиотеки

расширяя его, поле получает подтверждение

1)

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

TestCase

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

2) цифры

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

TestCase

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

3) мин и Макс

self.number = ko.observable(numberValue).extend({ min: 5}).расширение ({ max: 10});

это поле принимает значение от 5 до 10 только

TestCase

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

чтобы проверить, содержит ли переменная допустимое число, а не просто строка, которая выглядит как ряд, 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

вы можете свести к минимуму эту функцию, а также реализовать ее с помощью пользовательского регулярного выражения для отрицательных значений или пользовательских диаграмм:

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

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

если n числовое Number(n) вернет числовое значение и toString() превратит его обратно в строку. Но если n не числовое Number(n) вернутся NaN поэтому он не будет соответствовать оригиналу n