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