(Встроенный) способ в JavaScript, чтобы проверить, является ли строка допустимым числом
Я надеюсь, что что-то находится в том же концептуальном пространстве, что и старая IsNumeric()
VB6 IsNumeric()
?
Ответы
Ответ 1
Чтобы проверить, является ли переменная (включая строку) числом, проверьте, не является ли она числом:
Это работает независимо от того, является ли содержимое переменной строкой или числом.
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
Ответ 2
И вы могли бы пойти RegExp-путь:
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
}
Ответ 3
Если вы просто пытаетесь проверить, является ли строка целым числом (без десятичных разрядов), регулярное выражение является хорошим способом. Другие методы, такие как 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
Ответ 4
Если вы действительно хотите убедиться, что строка содержит только число, любое число (целая или плавающая точка) и точно число, вы не можете использовать 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()
возвращает число, когда это не должно, и наоборот. Итак, чтобы узнать, действительно ли строка точно и только номер, вызовите обе функции и посмотрите, вернут ли они оба истины:
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))
}
Ответ 5
Попробуйте функцию isNan:
Функция isNaN() определяет, является ли значение недопустимым числом (Not-a-Number).
Эта функция возвращает true, если значение равно NaN. В противном случае возвращается false.
Эта функция отличается от метода Number.isNaN(), специфичного для номера.
Глобальная функция isNaN() преобразует проверенное значение в число, а затем проверяет его.
Number.isNan() не преобразует значения в Number и не возвращает true для любого значения, которое не относится к типу Number...
Ответ 6
Принятый ответ на этот вопрос имеет довольно много недостатков (как было подчеркнуто несколькими другими пользователями). Это один из самых простых и проверенных способов подойти к нему в javascript:
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
Ниже приведены несколько хороших тестовых примеров:
console.log(isNumeric(12345678912345678912)); // true
console.log(isNumeric('2 ')); // true
console.log(isNumeric('-32.2 ')); // true
console.log(isNumeric(-32.2)); // true
console.log(isNumeric(undefined)); // false
// the accepted answer fails at these tests:
console.log(isNumeric('')); // false
console.log(isNumeric(null)); // false
console.log(isNumeric([])); // false
Ответ 7
Старый вопрос, но в данных ответах несколько точек.
Научная нотация.
!isNaN('1e+30')
true
, однако в большинстве случаев, когда люди запрашивают номера, они не хотят сопоставлять такие вещи, как 1e+30
.
Большие плавающие числа могут вести себя странно
Наблюдайте (используя Node.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);
}
Однако даже этот далеко не полный. Ведущие нули здесь не обрабатываются, но они проводят проверку длины.
Ответ 8
Я проверил, и решение Майкла является лучшим. Проголосуйте за его ответ выше (найдите на этой странице "Если вы действительно хотите убедиться в наличии строки", чтобы найти ее). По сути, его ответ таков:
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, [] (и других?)
Ответ 9
Вы можете использовать результат Number при передаче аргумента его конструктору.
Если аргумент (строка) не может быть преобразован в число, он возвращает 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
Ответ 10
Может быть, один или два человека сталкиваются с этим вопросом, которым нужна проверка гораздо более строгая, чем обычно (как и я). В этом случае это может быть полезно:
if(str === String(Number(str))) {
// it a "perfectly formatted" number
}
Осторожно! Это отклонит строки типа .1
, 40.000
, 080
, 00.1
. Это очень разборчиво - строка должна соответствовать " самой минимальной совершенной форме" номера для прохождения этого теста.
Он использует конструктор String
и Number
для перевода строки в число и обратно и, таким образом, проверяет, является ли движок JavaScript "идеальной минимальной формой" (тот, который он преобразовал с помощью начального конструктора Number
) соответствует исходной строке.
Ответ 11
parseInt(), но имейте в виду, что эта функция немного отличается в том смысле, что она, например, возвращает 100 для parseInt ( "100px" ).
Ответ 12
Почему реализация 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, и ответ Майкла, с дополнительной проверкой на ведущие/конечные пробелы (поскольку версия Michael возвращает 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));
};
Я не тестировал ни одно из них, другими способами, кроме ручного тестирования нескольких вариантов использования, которые я буду бить с моим текущим затруднительным положением, что является очень стандартным материалом. Это ситуация "стоящих на плечах гигантов".
Ответ 13
Ну, я использую этот, который я сделал...
Он работает до сих пор:
function checkNumber(value) {
if ( value % 1 == 0 )
return true;
else
return false;
}
Если вы заметили какие-либо проблемы с этим, скажите мне, пожалуйста.
Ответ 14
Цитата:
isNaN (num)//возвращает true, если переменная НЕ содержит допустимый номер
не совсем верно, если вам нужно проверить ведущие/конечные пробелы - например, когда требуется определенное количество цифр, и вам нужно получить, скажем, "1111", а не "111" или "111" для возможно, PIN-код.
Лучше использовать:
var num = /^\d+$/.test(num)
Ответ 15
Если кто-то когда-либо заходит так далеко, я потратил некоторое время на взломы, пытаясь исправить момент. 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
}
Обрабатывает следующие случаи:
True!
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))
False!
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
Любые предложения приветствуются.:]
Ответ 16
PFB - рабочее решение:
function(check){
check = check + "";
var isNumber = check.trim().length>0? !isNaN(check):false;
return isNumber;
}
Ответ 17
Избавьте себя от головной боли, пытаясь найти "встроенное" решение.
Там нет хорошего ответа, и чрезвычайно одобренный ответ в этой теме является неправильным.
npm install is-number
В JavaScript это не всегда так просто, как следует проверять, является ли значение числом. Обычно разработчики используют +, - или Number() для приведения строкового значения к числу (например, когда значения возвращаются из пользовательского ввода, совпадений регулярных выражений, анализаторов и т.д.). Но есть много неинтуитивных крайних случаев, которые дают неожиданные результаты:
console.log(+[]); //=> 0
console.log(+''); //=> 0
console.log(+' '); //=> 0
console.log(typeof NaN); //=> 'number'
Ответ 18
function isNumberCandidate(s) {
const str = (''+ s).trim();
if (str.length === 0) return false;
return !isNaN(+str);
}
console.log(isNumberCandidate('1')); // true
console.log(isNumberCandidate('a')); // false
console.log(isNumberCandidate('000')); // true
console.log(isNumberCandidate('1a')); // false
console.log(isNumberCandidate('1e')); // false
console.log(isNumberCandidate('1e-1')); // true
console.log(isNumberCandidate('123.3')); // true
console.log(isNumberCandidate('')); // false
console.log(isNumberCandidate(' ')); // false
console.log(isNumberCandidate(1)); // true
console.log(isNumberCandidate(0)); // true
console.log(isNumberCandidate(NaN)); // false
console.log(isNumberCandidate(undefined)); // false
console.log(isNumberCandidate(null)); // false
console.log(isNumberCandidate(-1)); // true
console.log(isNumberCandidate('-1')); // true
console.log(isNumberCandidate('-1.2')); // true
console.log(isNumberCandidate(0.0000001)); // true
console.log(isNumberCandidate('0.0000001')); // true
console.log(isNumberCandidate(Infinity)); // true
console.log(isNumberCandidate(-Infinity)); // true
console.log(isNumberCandidate('Infinity')); // true
if (isNumberCandidate(s)) {
// use +s as a number
+s ...
}
Ответ 19
Используя простой JavaScript:
Number.isNaN(Number('1')); // false
Number.isNaN(Number('asdf')); // true
Используя Lodash:
_.isNaN(_.toNumber('1')); // false
_.isNaN(_.toNumber('asdf')); // true
Ответ 20
Это недопустимо для TypeScript как:
declare function isNaN(number: number): boolean;
Для TypeScript вы можете использовать:
/^\d+$/.test(key)
Ответ 21
Моя попытка немного запутать, возможно, не лучшее решение
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
Ответ 22
Мне нравится простота этого.
Number.isNaN(Number(value))
Выше приведен обычный Javascript, но я использую его в сочетании с защитой от набора текста для интеллектуальной проверки типов. Это очень полезно для компилятора машинописного текста, чтобы дать вам правильный intellisense и без ошибок типа.
Машинописные надписи
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
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;
}
Типгард достаточно умен, чтобы ограничить тип width
в операторе if
ТОЛЬКО string
. Это позволяет компилятору разрешать width.endsWith(...)
который он не разрешил бы, если бы тип был string | number
string | number
Вы можете вызывать typeguard как хотите, isNotNumber
, isNumber
, isString
, isNotString
но я думаю, что isString
является двусмысленным и сложным для чтения.
Ответ 23
В моем приложении мы разрешаем только символы a-z A-Z и 0-9. Я нашел ответ выше, используя "string% 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)], я не могу говорить за это, но это именно то, что нам нужно.
Ответ 24
Мое решение:
// returns true for positive ints;
// no scientific notation, hexadecimals or floating point dots
var isPositiveInt = function(str) {
var result = true, chr;
for (var i = 0, n = str.length; i < n; i++) {
chr = str.charAt(i);
if ((chr < "0" || chr > "9") && chr != ",") { //not digit or thousands separator
result = false;
break;
};
if (i == 0 && (chr == "0" || chr == ",")) { //should not start with 0 or ,
result = false;
break;
};
};
return result;
};
Вы можете добавить дополнительные условия внутри цикла, чтобы соответствовать вашим потребностям.
Ответ 25
Вы можете использовать типы, например, с flow librar y, чтобы получить статическую проверку времени компиляции. Конечно, не очень полезно для ввода пользователем.
// @flow
function acceptsNumber(value: number) {
// ...
}
acceptsNumber(42); // Works!
acceptsNumber(3.14); // Works!
acceptsNumber(NaN); // Works!
acceptsNumber(Infinity); // Works!
acceptsNumber("foo"); // Error!
Ответ 26
Здесь однострочный, чтобы проверить, является ли sNum
допустимым числовым значением; он был протестирован для самых разных входов:
!isNaN(+s.replace(/\s|\$/g, '')); // returns True if numeric value
Ответ 27
Недавно я написал статью о том, как убедиться, что переменная является допустимым числом: https://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.md В статье объясняется, как обеспечить с плавающей запятой или целое число, если это важно (+x
против ~~x
).
В статье предполагается, что переменная является string
или number
для начала, а trim
доступен/заполнен. Нетрудно расширить его и на другие типы. Вот мясо этого:
// Check for a valid float
if (x == null
|| ("" + x).trim() === ""
|| isNaN(+x)) {
return false; // not a float
}
// Check for a valid integer
if (x == null
|| ("" + x).trim() === ""
|| ~~x !== +x) {
return false; // not an integer
}
Ответ 28
Просто используйте isNaN()
, это преобразует строку в число, и если получит правильное число, вернет false
...
isNaN("Alireza"); //return true
isNaN("123"); //return false
Ответ 29
Я использую следующее:
const isNumber = s => !isNaN(+s)
Ответ 30
Вот высокопроизводительная (2.5 * 10 ^ 7 итераций/с @3.8GHz Haswell) версия реализации isNumber. Он работает для каждого теста, который я смог найти (включая символы):
var isNumber = (function () {
var isIntegerTest = /^\d+$/;
var isDigitArray = [!0, !0, !0, !0, !0, !0, !0, !0, !0, !0];
function hasLeading0s (s) {
return !(typeof s !== 'string' ||
s.length < 2 ||
s[0] !== '0' ||
!isDigitArray[s[1]] ||
isIntegerTest.test(s));
}
var isWhiteSpaceTest = /\s/;
return function isNumber (s) {
var t = typeof s;
var n;
if (t === 'number') {
return (s <= 0) || (s > 0);
} else if (t === 'string') {
n = +s;
return !((!(n <= 0) && !(n > 0)) || n === '0' || hasLeading0s(s) || !(n !== 0 || !(s === '' || isWhiteSpaceTest.test(s))));
} else if (t === 'object') {
return !(!(s instanceof Number) || ((n = +s), !(n <= 0) && !(n > 0)));
}
return false;
};
})();