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

StackOverflow https://stackoverflow.com/questions/175739

  •  05-07-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

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

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

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

Другие советы

И вы можете пойти по пути 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
}

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

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

Попробуйте Функция isNaN:

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

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

Эта функция отличается от конкретной для номера Число.isNaN() способ.

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

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

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

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

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

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

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

Вы можете использовать результат 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

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

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

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

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

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

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

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

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

Пока это работает:

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

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

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

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

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

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

Ниже приведено решение, которое, скорее всего, имеет плохую производительность, но хорошие результаты. Это придумка, сделанная из реализации jQuery 1.12.4 и ответа Майкла, с дополнительной проверкой для пробелов в начале / конце (потому что версия Майкла возвращает 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));
};

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

Цитата:

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

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

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

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

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

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

Верно!:

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

Ложь!:

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

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

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

PFB рабочий раствор:

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

Моя попытка немного сбить с толку, Pherhaps не лучшее решение

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

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

Number.isNaN(Number(value))

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

Типографские надписи

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 | строка . Вы можете захотеть сделать логику в зависимости от того, является ли она строкой.

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 | номер .

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

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

Нет хорошего ответа, и крайне недооцененный ответ в этой теме неправильный.

npm install is-number

  

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

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

В моем приложении мы разрешаем использовать только символы a-z A-Z и 0-9 символов.Я нашел ответ выше, используя " строка % 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)], Я не могу говорить за это, но это именно то, что нам было нужно.

Мое решение:

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

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

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

// @flow

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

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

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

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

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

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

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

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

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

Использование простого JavaScript:

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

Использование Lodash:

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

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

объявить функцию isNaN (число: число): логическое значение;

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

<код> / ^ \ d + $ /. Тест (ключ)

Я делаю это так:

function isString(value)
{
    return value.length !== undefined;
}
function isNumber(value)
{
    return value.NaN !== undefined;
}

Конечно, isString () будет отключен, если вы передадите какой-то другой объект, для которого определена длина.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top