Проверка десятичных чисел в 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

54 ответа

Решение

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

// 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 isNaN & isFinite имеют запутанное поведение из-за принудительного преобразования в число. В ES6 Number.isNaN & Number.isFinite исправят эти проблемы. Имейте это в виду при их использовании.


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

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

Обновление: Angular 4.3:

export function isNumeric(value: any): boolean {
    return !isNaN(value - parseFloat(value));
}

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! Пользовательский интерфейс использует это:

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

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

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

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

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

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

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

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

Конечно, вы также можете использовать Array.isArray JQuery $.isArray или прототип Object.isArray вместо Object.prototype.toString.call(n) !== '[object Array]'

Вторая проблема заключалась в том, что строки букв с отрицательным шестнадцатеричным целым числом ("-0xA" -> -10) не считались числовыми. Тем не менее, положительные шестнадцатеричные целочисленные литеральные строки ("0xA" -> 10) считались числовыми. Мне нужно, чтобы оба были действительными числовыми.

Затем я изменил логику, чтобы принять это во внимание.

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

Если вы беспокоитесь о создании регулярного выражения при каждом вызове функции, то вы можете переписать его в закрытии, что-то вроде этого

var isNumber = (function () {
  var rx = /^-/;

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

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

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

РЕДАКТИРОВАТЬ: Как указал Берги, есть другие возможные объекты, которые можно считать числовыми, и было бы лучше, чтобы белый список, чем черный список. Имея это в виду, я бы добавил к критериям.

Я хочу, чтобы моя функция 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>

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

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

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

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

Начиная с 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 является действительным числом (гекса)

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

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

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

$.isNumeric(val)

Просто.

https://api.jquery.com/jQuery.isNumeric/ (по состоянию на jQuery 1.7)

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

isNumber : function(v){
   return typeof v === 'number' && isFinite(v);
}
return (input - 0) == input && input.length > 0;

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

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

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

Единственная проблема, с которой я столкнулся при ответе @CMS - исключение NaN и Бесконечность, которые являются полезными числами для многих ситуаций. Один из способов проверить NaNэто проверить числовые значения, которые не равны друг другу, NaN != NaN! Так что на самом деле есть 3 теста, с которыми вы хотели бы иметь дело...

function isNumber(n) {
  n = parseFloat(n);
  return !isNaN(n) || n != n;
}
function isFiniteNumber(n) {
  n = parseFloat(n);
  return !isNaN(n) && isFinite(n);
}    
function isComparableNumber(n) {
  n = parseFloat(n);
  return (n >=0 || n < 0);
}

isFiniteNumber('NaN')
false
isFiniteNumber('OxFF')
true
isNumber('NaN')
true
isNumber(1/0-1/0)
true
isComparableNumber('NaN')
false
isComparableNumber('Infinity')
true

Мой isComparableNumber довольно близок к другому элегантному ответу, но обрабатывает шестнадцатеричные и другие строковые представления чисел.

Если я не ошибаюсь, это должно соответствовать любому действительному значению числа 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

Я думаю, что функция parseFloat может сделать всю работу здесь. Функция ниже проходит все тесты на этой странице, включая isNumeric(Infinity) == true:

function isNumeric(n) {

    return parseFloat(n) == n;
}

Пара тестов для добавления:

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

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

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

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

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

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

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

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

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

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

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

Целочисленное значение можно проверить с помощью:

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

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

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

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

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

Мое решение,

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 isNumber(num) {
    return parseFloat(num).toString() == num
}

Это должно работать. Некоторые функции, представленные здесь, имеют недостатки, и должны быть быстрее, чем любая другая функция здесь.

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

Разъяснение:

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

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

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

Вот очень простой (проверенный в 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'));

Обратите внимание, что он считает бесконечность числом.

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

Ничего особенного, но мы можем использовать булев конструктор

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

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

Нет необходимости использовать дополнительную библиотеку.

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
Другие вопросы по тегам