(Встроенный) способ в JavaScript, чтобы проверить, является ли строка допустимым числом - PullRequest
949 голосов
/ 06 октября 2008

Я надеюсь, что есть что-то в том же концептуальном пространстве, что и старая функция VB6 IsNumeric()?

Ответы [ 30 ]

1945 голосов
/ 06 октября 2008

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

Это работает независимо от того, является ли содержимое переменной строкой или числом.

isNaN(num)         // returns true if the variable does NOT contain a valid number

Примеры * * 1 006 isNaN(123) // false isNaN('123') // false isNaN('1e10000') // false (This translates to Infinity, which is a number) isNaN('foo') // true isNaN('10px') // true Конечно, вы можете отрицать это, если вам нужно. Например, чтобы реализовать приведенный вами пример IsNumeric: function isNumeric(num){ return !isNaN(num) } Чтобы преобразовать строку, содержащую число, в число: Работает только в том случае, если строка only содержит числовые символы, в противном случае возвращается NaN. +num // returns the numeric value of the string, or NaN // if the string isn't purely numeric characters Примеры

+'12'              // 12
+'12.'             // 12
+'12..'            // Nan
+'.12'             // 0.12
+'..12'            // Nan
+'foo'             // NaN
+'12px'            // NaN

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

Полезно для преобразования 12px в 12, например:

parseInt(num)      // extracts a numeric value from the 
                   // start of the string, or NaN.

Примеры

parseInt('12')     // 12
parseInt('aaa')    // NaN
parseInt('12px')   // 12
parseInt('foo2')   // NaN      These last two may be different
parseInt('12a5')   // 12       from what you expected to see. 

поплавки

Имейте в виду, что, в отличие от +num, parseInt (как следует из названия) преобразует число с плавающей точкой в ​​целое число, отсекая все после десятичной точки (если вы хотите использовать parseInt() , потому что из этого поведения, вам, вероятно, лучше использовать другой метод вместо ):

+'12.345'          // 12.345
parseInt(12.345)   // 12
parseInt('12.345') // 12

Пустые строки

Пустые строки могут быть немного нелогичными. +num преобразует пустые строки в ноль, а isNaN() предполагает то же самое:

+''                // 0
isNaN('')          // false

Но parseInt() не согласен:

parseInt('')       // NaN
43 голосов
/ 06 октября 2008

И вы можете пойти по пути RegExp:

var num = "987238";

if(num.match(/^-{0,1}\d+$/)){
  //valid integer (positive or negative)
}else if(num.match(/^\d+\.\d+$/)){
  //valid float
}else{
  //not valid number
}
31 голосов
/ 27 июня 2014

Если вы просто пытаетесь проверить, является ли строка целым числом (без десятичных разрядов), регулярное выражение является хорошим способом. Другие методы, такие как isNaN, слишком сложны для чего-то такого простого.

function isNumeric(value) {
    return /^-{0,1}\d+$/.test(value);
}

console.log(isNumeric('abcd'));         // false
console.log(isNumeric('123a'));         // false
console.log(isNumeric('1'));            // true
console.log(isNumeric('1234567890'));   // true
console.log(isNumeric('-23'));          // true
console.log(isNumeric(1234));           // true
console.log(isNumeric('123.4'));        // false
console.log(isNumeric(''));             // false
console.log(isNumeric(undefined));      // false
console.log(isNumeric(null));           // false

Чтобы разрешить только положительные целые числа, используйте это:

function isNumeric(value) {
    return /^\d+$/.test(value);
}

console.log(isNumeric('123'));          // true
console.log(isNumeric('-23'));          // false
30 голосов
/ 03 марта 2016

Если вы действительно хотите убедиться, что строка содержит только число, любое число (целое или с плавающей запятой) и ровно число, вы не можете использовать parseInt() / parseFloat(), Number() или !isNaN() сами по себе. Обратите внимание, что !isNaN() фактически возвращает true, когда Number() вернет число, и false, когда оно вернет NaN, поэтому я исключу его из остальной части обсуждения.

Проблема с parseFloat() состоит в том, что он вернет число, если строка содержит любое число, даже если строка не содержит только и точно число:

parseFloat("2016-12-31")  // returns 2016
parseFloat("1-1") // return 1
parseFloat("1.2.3") // returns 1.2

Проблема с Number() заключается в том, что он вернет число в тех случаях, когда переданное значение вообще не является числом!

Number("") // returns 0
Number(" ") // returns 0
Number(" \u00A0   \t\n\r") // returns 0

Проблема с прокруткой вашего собственного регулярного выражения заключается в том, что если вы не создадите точное регулярное выражение для сопоставления числа с плавающей запятой, как Javascript распознает его, вы пропустите дела или узнаете случаи, в которых не следует. И даже если вы можете бросить свое собственное регулярное выражение, почему? Есть более простые встроенные способы сделать это.

Однако оказывается, что Number()isNaN()) делает правильные вещи для каждого случая, когда parseFloat() возвращает число, когда это не должно, и наоборот. Поэтому, чтобы выяснить, является ли строка действительно точной и только числом, вызовите обе функции и посмотрите, вернут ли они оба true:

function isNumber(str) {
  if (typeof str != "string") return false // we only process strings!
  // could also coerce to string: str = ""+str
  return !isNaN(str) && !isNaN(parseFloat(str))
}
21 голосов
/ 06 октября 2008

Попробуйте функцию isNan :

Функция isNaN () определяет, является ли значение недопустимым числом (Not-a-Number).

Эта функция возвращает true, если значение равно NaN. В противном случае возвращается false.

Эта функция отличается от метода Number * Number.isNaN () .

Глобальная функция isNaN () преобразует проверенное значение в число, а затем проверяет его.

Number.isNan () не преобразует значения в число и не возвращает значение true для любого значения, которое не относится к типу число ...

11 голосов
/ 02 октября 2013

Старый вопрос, но в данных ответах не хватает нескольких пунктов.

Научная запись.

!isNaN('1e+30') - это true, однако в большинстве случаев, когда люди спрашивают цифры, они не хотят сопоставлять такие вещи, как 1e+30.

Большие плавающие числа могут вести себя странно

Наблюдать (используя Node.js):

> var s = Array(16 + 1).join('9')
undefined
> s.length
16
> s
'9999999999999999'
> !isNaN(s)
true
> Number(s)
10000000000000000
> String(Number(s)) === s
false
>

С другой стороны:

> var s = Array(16 + 1).join('1')
undefined
> String(Number(s)) === s
true
> var s = Array(15 + 1).join('9')
undefined
> String(Number(s)) === s
true
>

Итак, если вы ожидаете String(Number(s)) === s, то лучше ограничить строки не более 15 цифрами (после пропуска ведущих нулей).

Бесконечность

> typeof Infinity
'number'
> !isNaN('Infinity')
true
> isFinite('Infinity')
false
>

Учитывая все это, проверяем, что данная строка является числом, удовлетворяющим всем следующим условиям:

  • ненаучная запись
  • предсказуемое преобразование в Number и обратно в String
  • конечный

не такая простая задача. Вот простая версия:

  function isNonScientificNumberString(o) {
    if (!o || typeof o !== 'string') {
      // Should not be given anything but strings.
      return false;
    }
    return o.length <= 15 && o.indexOf('e+') < 0 && o.indexOf('E+') < 0 && !isNaN(o) && isFinite(o);
  }

Однако даже это далеко не завершено. Ведущие нули здесь не обрабатываются, но они проверяют длину.

7 голосов
/ 25 октября 2018

Принятый ответ на этот вопрос имеет довольно много недостатков (как было подчеркнуто несколькими другими пользователями). Это один из самых простых и проверенных способов подойти к нему в javascript:

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

Ниже приведены несколько хороших тестовых примеров:

console.log(isNumeric(12345678912345678912)); // true
console.log(isNumeric('2 '));                 // true
console.log(isNumeric('-32.2 '));             // true
console.log(isNumeric(-32.2));                // true
console.log(isNumeric(undefined));            // false

// the accepted answer fails at these tests:
console.log(isNumeric(''));                   // false
console.log(isNumeric(null));                 // false
console.log(isNumeric([]));                   // false
6 голосов
/ 09 января 2017

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

if(str === String(Number(str))) {
  // it's a "perfectly formatted" number
}

Осторожно! Это будет отклонять строки, такие как .1, 40.000, 080, 00.1. Это очень придирчиво - строка должна соответствовать " самой минимальной совершенной форме " числа, чтобы этот тест прошел.

Он использует конструкторы String и Number для приведения строки к числу и обратно и таким образом проверяет, является ли механизм движка JavaScript "идеальной минимальной формой" (той, в которую он был преобразован с помощью начального конструктора Number ) соответствует исходной строке.

6 голосов
/ 21 февраля 2017

Я проверил, и решение Майкла лучшее. Проголосуйте за его ответ выше (найдите на этой странице «Если вы действительно хотите убедиться, что строка», чтобы найти его). По сути, его ответ таков:

function isNumeric(num){
  num = "" + num; //coerce num to be a string
  return !isNaN(num) && !isNaN(parseFloat(num));
}

Это работает для каждого теста, который я задокументировал здесь: https://jsfiddle.net/wggehvp9/5/

Многие другие решения терпят неудачу для этих крайних случаев: '', null, "", true и []. Теоретически, вы можете использовать их с правильной обработкой ошибок, например:

return !isNaN(num);

или

return (+num === +num);

со специальной обработкой для / \ s /, null, "", true, false, [] (и другие?)

5 голосов
/ 06 октября 2008

parseInt (), но имейте в виду, что эта функция немного отличается в том смысле, что она, например, возвращает 100 для parseInt ("100px").

...