(Встроенный) способ в JavaScript, чтобы проверить, является ли строка допустимым числом

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

Ответы

Ответ 1

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

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

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

Примеры

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

Чтобы преобразовать строку, содержащую число, в число:

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

Ответ 2

И вы могли бы пойти 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
}

Ответ 3

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

Ответ 4

Если вы действительно хотите убедиться, что строка содержит только число, любое число (целая или плавающая точка) и точно число, вы не можете использовать 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() возвращает число, когда это не должно, и наоборот. Итак, чтобы узнать, действительно ли строка точно и только номер, вызовите обе функции и посмотрите, вернут ли они оба истины:

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

Ответ 5

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

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

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

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

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

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

Ответ 6

Принятый ответ на этот вопрос имеет довольно много недостатков (как было подчеркнуто несколькими другими пользователями). Это один из самых простых и проверенных способов подойти к нему в 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

Ответ 7

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

Научная нотация.

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

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

Ответ 8

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

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, [] (и других?)

Ответ 9

Вы можете использовать результат Number при передаче аргумента его конструктору.

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

Примечания: Обратите внимание, что при пропуске пустой строки или '\t\t' и '\n\t' в качестве числа будет возвращаться 0; Передача true вернет 1, а false вернет 0.

    Number('34.00') // 34
    Number('-34') // -34
    Number('123e5') // 12300000
    Number('123e-5') // 0.00123
    Number('999999999999') // 999999999999
    Number('9999999999999999') // 10000000000000000 (integer accuracy up to 15 digit)
    Number('0xFF') // 255
    Number('Infinity') // Infinity  

    Number('34px') // NaN
    Number('xyz') // NaN
    Number('true') // NaN
    Number('false') // NaN

    // cavets
    Number('    ') // 0
    Number('\t\t') // 0
    Number('\n\t') // 0

Ответ 10

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

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

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

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

Ответ 11

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

Ответ 12

Почему реализация jQuery не достаточно хороша?

function isNumeric(a) {
    var b = a && a.toString();
    return !$.isArray(a) && b - parseFloat(b) + 1 >= 0;
};

Майкл предложил что-то вроде этого (хотя я украл "user1691651 - John" измененную версию здесь):

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

Ниже приведено решение с наиболее вероятной плохими характеристиками, но с твердыми результатами. Это приложение, сделанное из реализации jQuery 1.12.4, и ответ Майкла, с дополнительной проверкой на ведущие/конечные пробелы (поскольку версия Michael возвращает true для чисел с ведущими/конечными пробелами):

function isNumeric(a) {
    var str = a + "";
    var b = a && a.toString();
    return !$.isArray(a) && b - parseFloat(b) + 1 >= 0 &&
           !/^\s+|\s+$/g.test(str) &&
           !isNaN(str) && !isNaN(parseFloat(str));
};

Последняя версия имеет две новые переменные. Можно обойти одну из них, выполнив:

function isNumeric(a) {
    if ($.isArray(a)) return false;
    var b = a && a.toString();
    a = a + "";
    return b - parseFloat(b) + 1 >= 0 &&
            !/^\s+|\s+$/g.test(a) &&
            !isNaN(a) && !isNaN(parseFloat(a));
};

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

Ответ 13

Ну, я использую этот, который я сделал...

Он работает до сих пор:

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

Если вы заметили какие-либо проблемы с этим, скажите мне, пожалуйста.

Ответ 14

Цитата:

isNaN (num)//возвращает true, если переменная НЕ содержит допустимый номер

не совсем верно, если вам нужно проверить ведущие/конечные пробелы - например, когда требуется определенное количество цифр, и вам нужно получить, скажем, "1111", а не "111" или "111" для возможно, PIN-код.

Лучше использовать:

var num = /^\d+$/.test(num)

Ответ 15

Если кто-то когда-либо заходит так далеко, я потратил некоторое время на взломы, пытаясь исправить момент. js (https://github.com/moment/moment). Вот что я отнял у него:

function isNumeric(val) {
    var _val = +val;
    return (val !== val + 1) //infinity check
        && (_val === +val) //Cute coercion check
        && (typeof val !== 'object') //Array/object check
}

Обрабатывает следующие случаи:

True!

isNumeric("1"))
isNumeric(1e10))
isNumeric(1E10))
isNumeric(+"6e4"))
isNumeric("1.2222"))
isNumeric("-1.2222"))
isNumeric("-1.222200000000000000"))
isNumeric("1.222200000000000000"))
isNumeric(1))
isNumeric(0))
isNumeric(-0))
isNumeric(1010010293029))
isNumeric(1.100393830000))
isNumeric(Math.LN2))
isNumeric(Math.PI))
isNumeric(5e10))

False!

isNumeric(NaN))
isNumeric(Infinity))
isNumeric(-Infinity))
isNumeric())
isNumeric(undefined))
isNumeric('[1,2,3]'))
isNumeric({a:1,b:2}))
isNumeric(null))
isNumeric([1]))
isNumeric(new Date()))

По иронии судьбы, тот, с которым я боюсь больше всего:

isNumeric(new Number(1)) => false

Любые предложения приветствуются.:]

Ответ 16

PFB - рабочее решение:

 function(check){ 
    check = check + "";
    var isNumber =   check.trim().length>0? !isNaN(check):false;
    return isNumber;
    }

Ответ 17

Избавьте себя от головной боли, пытаясь найти "встроенное" решение.

Там нет хорошего ответа, и чрезвычайно одобренный ответ в этой теме является неправильным.

npm install is-number

В JavaScript это не всегда так просто, как следует проверять, является ли значение числом. Обычно разработчики используют +, - или Number() для приведения строкового значения к числу (например, когда значения возвращаются из пользовательского ввода, совпадений регулярных выражений, анализаторов и т.д.). Но есть много неинтуитивных крайних случаев, которые дают неожиданные результаты:

console.log(+[]); //=> 0
console.log(+''); //=> 0
console.log(+'   '); //=> 0
console.log(typeof NaN); //=> 'number'

Ответ 18

function isNumberCandidate(s) {
  const str = (''+ s).trim();
  if (str.length === 0) return false;
  return !isNaN(+str);
}

console.log(isNumberCandidate('1'));       // true
console.log(isNumberCandidate('a'));       // false
console.log(isNumberCandidate('000'));     // true
console.log(isNumberCandidate('1a'));      // false 
console.log(isNumberCandidate('1e'));      // false
console.log(isNumberCandidate('1e-1'));    // true
console.log(isNumberCandidate('123.3'));   // true
console.log(isNumberCandidate(''));        // false
console.log(isNumberCandidate(' '));       // false
console.log(isNumberCandidate(1));         // true
console.log(isNumberCandidate(0));         // true
console.log(isNumberCandidate(NaN));       // false
console.log(isNumberCandidate(undefined)); // false
console.log(isNumberCandidate(null));      // false
console.log(isNumberCandidate(-1));        // true
console.log(isNumberCandidate('-1'));      // true
console.log(isNumberCandidate('-1.2'));    // true
console.log(isNumberCandidate(0.0000001)); // true
console.log(isNumberCandidate('0.0000001')); // true
console.log(isNumberCandidate(Infinity));    // true
console.log(isNumberCandidate(-Infinity));    // true

console.log(isNumberCandidate('Infinity'));  // true

if (isNumberCandidate(s)) {
  // use +s as a number
  +s ...
}

Ответ 19

Используя простой JavaScript:

Number.isNaN(Number('1')); // false
Number.isNaN(Number('asdf')); // true

Используя Lodash:

_.isNaN(_.toNumber('1')); // false
_.isNaN(_.toNumber('asdf')); // true

Ответ 20

Это недопустимо для TypeScript как:

declare function isNaN(number: number): boolean;

Для TypeScript вы можете использовать:

/^\d+$/.test(key)

Ответ 21

Моя попытка немного запутать, возможно, не лучшее решение

function isInt(a){
    return a === ""+~~a
}


console.log(isInt('abcd'));         // false
console.log(isInt('123a'));         // false
console.log(isInt('1'));            // true
console.log(isInt('0'));            // true
console.log(isInt('-0'));           // false
console.log(isInt('01'));           // false
console.log(isInt('10'));           // true
console.log(isInt('-1234567890'));  // true
console.log(isInt(1234));           // true
console.log(isInt('123.4'));        // false
console.log(isInt(''));             // false

// other types then string returns false
console.log(isInt(5));              // false
console.log(isInt(undefined));      // false
console.log(isInt(null));           // false
console.log(isInt('0x1'));          // false
console.log(isInt(Infinity));       // false

Ответ 22

Мне нравится простота этого.

Number.isNaN(Number(value))

Выше приведен обычный Javascript, но я использую его в сочетании с защитой от набора текста для интеллектуальной проверки типов. Это очень полезно для компилятора машинописного текста, чтобы дать вам правильный intellisense и без ошибок типа.

Машинописные надписи

isNotNumber(value: string | number): value is string {
    return Number.isNaN(Number(this.smartImageWidth));
}
isNumber(value: string | number): value is number {
    return Number.isNaN(Number(this.smartImageWidth)) === false;
}

Допустим, у вас есть свойство width которая является number | string number | string Вы можете захотеть сделать логику в зависимости от того, является ли она строкой.

var width: number|string;
width = "100vw";

if (isNotNumber(width)) 
{
    // the compiler knows that width here must be a string
    if (width.endsWith('vw')) 
    {
        // we have a 'width' such as 100vw
    } 
}
else 
{
    // the compiler is smart and knows width here must be number
    var doubleWidth = width * 2;    
}

Типгард достаточно умен, чтобы ограничить тип width в операторе if ТОЛЬКО string. Это позволяет компилятору разрешать width.endsWith(...) который он не разрешил бы, если бы тип был string | number string | number

Вы можете вызывать typeguard как хотите, isNotNumber, isNumber, isString, isNotString но я думаю, что isString является двусмысленным и сложным для чтения.

Ответ 23

В моем приложении мы разрешаем только символы a-z A-Z и 0-9. Я нашел ответ выше, используя "string% 1 === 0", если строка не начиналась с 0xnn (например, 0x10), а затем она возвращала бы ее как числовую, когда мы этого не хотели. Следующая простая ловушка в моей числовой проверке, похоже, делает трюк в наших конкретных случаях.

function isStringNumeric(str_input){   
    //concat a temporary 1 during the modulus to keep a beginning hex switch combination from messing us up   
    //very simple and as long as special characters (non a-z A-Z 0-9) are trapped it is fine   
    return '1'.concat(str_input) % 1 === 0;}

Предупреждение. Это может быть использование давней ошибки в Javascript и Actionscript [Number ( "1" + the_string)% 1 === 0)], я не могу говорить за это, но это именно то, что нам нужно.

Ответ 24

Мое решение:

// returns true for positive ints; 
// no scientific notation, hexadecimals or floating point dots

var isPositiveInt = function(str) { 
   var result = true, chr;
   for (var i = 0, n = str.length; i < n; i++) {
       chr = str.charAt(i);
       if ((chr < "0" || chr > "9") && chr != ",") { //not digit or thousands separator
         result = false;
         break;
       };
       if (i == 0 && (chr == "0" || chr == ",")) {  //should not start with 0 or ,
         result = false;
         break;
       };
   };
   return result;
 };

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

Ответ 25

Вы можете использовать типы, например, с flow librar y, чтобы получить статическую проверку времени компиляции. Конечно, не очень полезно для ввода пользователем.

// @flow

function acceptsNumber(value: number) {
  // ...
}

acceptsNumber(42);       // Works!
acceptsNumber(3.14);     // Works!
acceptsNumber(NaN);      // Works!
acceptsNumber(Infinity); // Works!
acceptsNumber("foo");    // Error!

Ответ 26

Здесь однострочный, чтобы проверить, является ли sNum допустимым числовым значением; он был протестирован для самых разных входов:

!isNaN(+s.replace(/\s|\$/g, ''));  // returns True if numeric value

Ответ 27

Недавно я написал статью о том, как убедиться, что переменная является допустимым числом: https://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.md В статье объясняется, как обеспечить с плавающей запятой или целое число, если это важно (+x против ~~x).

В статье предполагается, что переменная является string или number для начала, а trim доступен/заполнен. Нетрудно расширить его и на другие типы. Вот мясо этого:

// Check for a valid float
if (x == null
    || ("" + x).trim() === ""
    || isNaN(+x)) {
    return false;  // not a float
}

// Check for a valid integer
if (x == null
    || ("" + x).trim() === ""
    || ~~x !== +x) {
    return false;  // not an integer
}

Ответ 28

Просто используйте isNaN(), это преобразует строку в число, и если получит правильное число, вернет false...

isNaN("Alireza"); //return true
isNaN("123"); //return false

Ответ 29

Я использую следующее:

const isNumber = s => !isNaN(+s)

Ответ 30

Вот высокопроизводительная (2.5 * 10 ^ 7 итераций/с @3.8GHz Haswell) версия реализации isNumber. Он работает для каждого теста, который я смог найти (включая символы):

var isNumber = (function () {
  var isIntegerTest = /^\d+$/;
  var isDigitArray = [!0, !0, !0, !0, !0, !0, !0, !0, !0, !0];
  function hasLeading0s (s) {
    return !(typeof s !== 'string' ||
    s.length < 2 ||
    s[0] !== '0' ||
    !isDigitArray[s[1]] ||
    isIntegerTest.test(s));
  }
  var isWhiteSpaceTest = /\s/;
  return function isNumber (s) {
    var t = typeof s;
    var n;
    if (t === 'number') {
      return (s <= 0) || (s > 0);
    } else if (t === 'string') {
      n = +s;
      return !((!(n <= 0) && !(n > 0)) || n === '0' || hasLeading0s(s) || !(n !== 0 || !(s === '' || isWhiteSpaceTest.test(s))));
    } else if (t === 'object') {
      return !(!(s instanceof Number) || ((n = +s), !(n <= 0) && !(n > 0)));
    }
    return false;
  };
})();