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

javascript validation numbers

1426640 просмотра

30 ответа

Какой самый чистый и эффективный способ проверки десятичных чисел в 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
Автор: Michael Haren Источник Размещён: 17.05.2019 03:20

Ответы (30)


2803 плюса

Решение

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

// 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));
}
Автор: CMS Размещён: 02.12.2009 05:36

318 плюса

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 ().

Автор: Joel Coehoorn Размещён: 06.10.2008 04:04

59 плюса

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

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
Автор: Michael Haren Размещён: 20.08.2008 02:22

47 плюса

Yahoo! Пользовательский интерфейс использует это:

isNumber: function(o) {
    return typeof o === 'number' && isFinite(o);
}
Автор: camomileCase Размещён: 14.08.2009 09:07

45 плюса

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

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

Автор: user189277 Размещён: 13.10.2009 05:05

38 плюса

Принятый ответ не прошел тест №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.isArrayJQuery $.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>

Автор: Xotic750 Размещён: 23.02.2013 06:25

31 плюса

Да, встроенный 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
Автор: travis Размещён: 21.08.2008 04:05

14 плюса

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

Автор: Kuf Размещён: 18.02.2013 09:01

14 плюса

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

Автор: bubbassauro Размещён: 21.08.2008 01:02

10 плюса

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

function IsNumeric(data){
    return parseFloat(data)==data;
}
Автор: Aquatic Размещён: 22.08.2008 03:08

5 плюса

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

$.isNumeric(val)

Просто.

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

Автор: Sean the Bean Размещён: 13.01.2014 04:42

5 плюса

Если я не ошибаюсь, это должно соответствовать любому действительному значению числа 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
Автор: Hans Schmucker Размещён: 12.06.2012 08:09

5 плюса

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

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

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

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

Автор: jayakumar Размещён: 28.01.2011 11:22

4 плюса

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

isNumber : function(v){
   return typeof v === 'number' && isFinite(v);
}
Автор: InsertNameHere Размещён: 28.05.2010 11:30

4 плюса

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

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

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

Автор: solidarius Размещён: 10.06.2011 12:27

4 плюса

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

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

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

Автор: Arman McHitarian Размещён: 20.05.2013 04:48

4 плюса

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

Автор: hobs Размещён: 06.06.2013 11:39

3 плюса

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

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

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

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

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

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

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

Похоже, работает в любой ситуации, но я могу ошибаться.

Автор: Manusoftar Размещён: 11.02.2011 11:48

3 плюса

This should work. Some of the functions provided here are flawed, also should be faster than any other function here.

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

Explained:

Create a copy of itself, then converts the number into float, then compares itself with the original number, if it is still a number, (whether integer or float) , and matches the original number, that means, it is indeed a number.

It works with numeric strings as well as plain numbers. Does not work with hexadecimal numbers.

Warning: use at your own risk, no guarantees.

Автор: user532188 Размещён: 06.12.2010 11:30

3 плюса

I'd like to add the following:

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

Positive hex numbers start with 0x and negative hex numbers start with -0x. Positive oct numbers start with 0 and negative oct numbers start with -0. This one takes most of what has already been mentioned into consideration, but includes hex and octal numbers, negative scientific, Infinity and has removed decimal scientific (4e3.2 is not valid).

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));
}
Автор: Marius Размещён: 20.08.2008 03:40

2 плюса

I'm using simpler solution:

function isNumber(num) {
    return parseFloat(num).toString() == num
}
Автор: Ali Gonabadi Размещён: 16.06.2012 12:25

2 плюса

None of the answers return false for empty strings, a fix for that...

function is_numeric(n)
{
 return (n != '' && !isNaN(parseFloat(n)) && isFinite(n));
}
Автор: John Размещён: 23.12.2014 02:38

2 плюса

To check if a variable contains a valid number and not just a String which looks like a number, Number.isFinite(value) can be used.

This is part of the language since ES2015

Examples:

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
Автор: adius Размещён: 10.04.2016 05:53

1 плюс

@CMS 'answer : Ваш фрагмент не был выполнен в случаях пропусков на моем компьютере с использованием 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'
    ];

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

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

Здесь все работает как положено. Может быть, это помогает.

Полный исходный код для этого можно найти здесь .

Автор: Phil Размещён: 14.04.2013 10:14

1 плюс

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

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

Это основано на этом ответе (и для этого ответа): https://stackoverflow.com/a/1561597/1985601

Автор: daniel1426 Размещён: 20.12.2013 10:01

1 плюс

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

Следует отметить, что предполагается, что «.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.
Автор: donquixote Размещён: 13.04.2014 11:28

1 плюс

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

Расширяя его, поле проверяется

1) номер

self.number = ko.observable(numberValue).extend ({число: правда}) ;

Прецедент

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 ({цифра: правда}) ;

Прецедент

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 ({мин: 5}). удлинение ({макс: 10}) ;

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

Прецедент

numberValue = '5'    --> true
numberValue = '6'    --> true
numberValue = '6.5'  --> true
numberValue = '9'    --> true
numberValue = '11'   --> false
numberValue = '0'    --> false
numberValue = ''    --> false
Автор: nav0611 Размещён: 27.02.2013 03:38

1 плюс

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

$('.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)
});
Автор: Vixed Размещён: 23.02.2017 02:56

1 плюс

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

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

Автор: chrmcpn Размещён: 10.08.2016 08:17
Вопросы из категории :
32x32