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