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