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


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

19 827

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

однако, оказывается, что 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') и 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' как число вернет 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 конструктор) соответствует исходной строке.

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

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). Вот что я у него отнял:

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 для умной проверки типа. Это очень полезно для компилятора typescript, чтобы дать вам правильный intellisense, и никаких ошибок типа.

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