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

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

19 ответов


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

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

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

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

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

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

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

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

parseInt('')       // NaN

и вы можете пойти RegExp-way:

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
}

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

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

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

попробовать функция isNan:

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

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

эта функция отличается от номера конкретного количество.isNaN() метод.

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

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


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

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

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

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

соблюдать (через узел.в 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);
  }

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


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


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

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

Примечания: Примечание при передаче пустой строки или '\t\t' и '\n\t' as Number вернет 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 конструктор) соответствует исходной строке.


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

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


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

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

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

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


цитата:

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

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

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

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

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

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


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

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

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

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


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

Number.isNaN(Number(value))

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

машинопись typeguards

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

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

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

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


в моем приложении мы разрешаем только 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)], я не могу говорить об этом, но это именно то, что нам нужно.