如何检查字符串是否是有效数字?

发布于 2024-07-06 10:00:20 字数 61 浏览 11 评论 0原文

我希望有一些东西与旧的 VB6 IsNumeric() 函数处于相同的概念空间中?

I'm hoping there's something in the same conceptual space as the old VB6 IsNumeric() function?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

凡间太子 2024-07-13 10:00:20

2020 年 10 月 2 日:请注意,许多简单的方法都充满了微妙的错误(例如空格、隐式部分解析、基数、数组强制转换等),这里的许多答案都未能考虑到这些错误帐户。 以下实现可能适合您,但请注意,它不支持除小数点“.”之外的数字分隔符:

function isNumeric(str) {
  if (typeof str != "string") return false // we only process strings!  
  return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...
         !isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail
}

要检查变量(包括字符串)是否为数字,请检查是否它不是数字:

无论变量内容是字符串还是数字,这都有效。

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
isNaN('')          // false
isNaN(' ')         // false
isNaN(false)       // false

当然,如果需要,您可以否定这一点。 例如,要实现您给出的 IsNumeric 示例:

function isNumeric(num){
  return !isNaN(num)
}

将包含数字的字符串转换为数字:

仅当字符串 only 包含数字字符时才有效,否则返回 <代码>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 three may
parseInt('12a5')   // 12       be different from what
parseInt('0x10')   // 16       you expected to see.

浮点数

请记住,与 +num 不同,parseInt (作为顾名思义)将通过去掉小数点后面的所有内容将浮点数转换为整数(如果您想使用 parseInt() 因为这种行为,您可能最好使用另一种方法):

+'12.345'          // 12.345
parseInt(12.345)   // 12
parseInt('12.345') // 12

空字符串

空字符串可能有点违反直觉。 +num 将空字符串或带空格的字符串转换为零,并且 isNaN() 假设相同:

+''                // 0
+'   '             // 0
isNaN('')          // false
isNaN('   ')       // false

parseInt() 不同意:

parseInt('')       // NaN
parseInt('   ')    // NaN

2nd October 2020: note that many bare-bones approaches are fraught with subtle bugs (eg. whitespace, implicit partial parsing, radix, coercion of arrays etc.) that many of the answers here fail to take into account. The following implementation might work for you, but note that it does not cater for number separators other than the decimal point ".":

function isNumeric(str) {
  if (typeof str != "string") return false // we only process strings!  
  return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...
         !isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail
}

To check if a variable (including a string) is a number, check if it is not a number:

This works regardless of whether the variable content is a string or number.

isNaN(num)         // returns true if the variable does NOT contain a valid number

Examples

isNaN(123)         // false
isNaN('123')       // false
isNaN('1e10000')   // false (This translates to Infinity, which is a number)
isNaN('foo')       // true
isNaN('10px')      // true
isNaN('')          // false
isNaN(' ')         // false
isNaN(false)       // false

Of course, you can negate this if you need to. For example, to implement the IsNumeric example you gave:

function isNumeric(num){
  return !isNaN(num)
}

To convert a string containing a number into a number:

Only works if the string only contains numeric characters, else it returns NaN.

+num               // returns the numeric value of the string, or NaN 
                   // if the string isn't purely numeric characters

Examples

+'12'              // 12
+'12.'             // 12
+'12..'            // NaN
+'.12'             // 0.12
+'..12'            // NaN
+'foo'             // NaN
+'12px'            // NaN

To convert a string loosely to a number

Useful for converting '12px' to 12, for example:

parseInt(num)      // extracts a numeric value from the 
                   // start of the string, or NaN.

Examples

parseInt('12')     // 12
parseInt('aaa')    // NaN
parseInt('12px')   // 12
parseInt('foo2')   // NaN      These last three may
parseInt('12a5')   // 12       be different from what
parseInt('0x10')   // 16       you expected to see.

Floats

Bear in mind that, unlike +num, parseInt (as the name suggests) will convert a float into an integer by chopping off everything following the decimal point (if you want to use parseInt() because of this behaviour, you're probably better off using another method instead):

+'12.345'          // 12.345
parseInt(12.345)   // 12
parseInt('12.345') // 12

Empty strings

Empty strings may be a little counter-intuitive. +num converts empty strings or strings with spaces to zero, and isNaN() assumes the same:

+''                // 0
+'   '             // 0
isNaN('')          // false
isNaN('   ')       // false

But parseInt() does not agree:

parseInt('')       // NaN
parseInt('   ')    // NaN
公布 2024-07-13 10:00:20

如果您只是想检查字符串是否是整数(没有小数位),则正则表达式是一个好方法。 其他方法(例如 isNaN)对于如此简单的事情来说太复杂了。

function isNumeric(value) {
    return /^-?\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(1234n));          // 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

If you're just trying to check if a string is a whole number (no decimal places), regex is a good way to go. Other methods such as isNaN are too complicated for something so simple.

function isNumeric(value) {
    return /^-?\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(1234n));          // true
console.log(isNumeric('123.4'));        // false
console.log(isNumeric(''));             // false
console.log(isNumeric(undefined));      // false
console.log(isNumeric(null));           // false

To only allow positive whole numbers use this:

function isNumeric(value) {
    return /^\d+$/.test(value);
}

console.log(isNumeric('123'));          // true
console.log(isNumeric('-23'));          // false
岁吢 2024-07-13 10:00:20

这个问题的公认答案有很多缺陷(正如其他几个用户所强调的那样)。 这是最简单的方法之一。 在 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

The accepted answer for this question has quite a few flaws (as highlighted by couple of other users). This is one of the easiest & proven way to approach it in javascript:

function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

Below are some good test cases:

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
任性一次 2024-07-13 10:00:20

你可以采用 RegExp 方式:

var num = "987238";

if(num.match(/^-?\d+$/)){
  //valid integer (positive or negative)
}else if(num.match(/^\d+\.\d+$/)){
  //valid float
}else{
  //not valid number
}

And you could go the RegExp-way:

var num = "987238";

if(num.match(/^-?\d+$/)){
  //valid integer (positive or negative)
}else if(num.match(/^\d+\.\d+$/)){
  //valid float
}else{
  //not valid number
}
待天淡蓝洁白时 2024-07-13 10:00:20

如果您确实想确保字符串仅包含数字、任何数字(整数或浮点数)以及确切的数字,则不能使用parseInt()/ parseFloat()Number()!isNaN() 本身。 请注意,当 Number() 返回数字时,!isNaN() 实际上返回 true,而当 Number() 返回数字时,则返回 false它将返回 NaN,因此我将把它排除在其余讨论之外。

parseFloat() 的问题是,如果字符串包含任何数字,即使该字符串不包含 only完全,它也会返回一个数字em> 数字:

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 识别的浮点数,否则你将错过一些情况或识别出不应该的情况。 即使您可以推出自己的正则表达式,为什么呢? 有更简单的内置方法可以做到这一点。

然而,事实证明,对于 parseFloat() 返回数字的每种情况,Number()(和 isNaN())都做了正确的事情当不应该的时候,反之亦然。 因此,要查明一个字符串是否确实是一个数字,请调用这两个函数并查看它们是否都返回 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))
}

If you really want to make sure that a string contains only a number, any number (integer or floating point), and exactly a number, you cannot use parseInt()/ parseFloat(), Number(), or !isNaN() by themselves. Note that !isNaN() is actually returning true when Number() would return a number, and false when it would return NaN, so I will exclude it from the rest of the discussion.

The problem with parseFloat() is that it will return a number if the string contains any number, even if the string doesn't contain only and exactly a number:

parseFloat("2016-12-31")  // returns 2016
parseFloat("1-1") // return 1
parseFloat("1.2.3") // returns 1.2

The problem with Number() is that it will return a number in cases where the passed value is not a number at all!

Number("") // returns 0
Number(" ") // returns 0
Number(" \u00A0   \t\n\r") // returns 0

The problem with rolling your own regex is that unless you create the exact regex for matching a floating point number as Javascript recognizes it you are going to miss cases or recognize cases where you shouldn't. And even if you can roll your own regex, why? There are simpler built-in ways to do it.

However, it turns out that Number() (and isNaN()) does the right thing for every case where parseFloat() returns a number when it shouldn't, and vice versa. So to find out if a string is really exactly and only a number, call both functions and see if they both 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))
}
流殇 2024-07-13 10:00:20

2019:包括 ES3、ES6 和 TypeScript 示例

也许这已经被重复了太多次,但是我今天也与这个问题作斗争,并想发布我的答案,因为我没有看到任何其他答案可以如此简单或彻底地做到这一点:

ES3

var isNumeric = function(num){
    return (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);  
}

ES6

const isNumeric = (num) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);

Typescript

const isNumeric = (num: any) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num as number);

这看起来很简单,涵盖了我在许多其他帖子中看到并自己想到的所有基础:

// Positive Cases
console.log(0, isNumeric(0) === true);
console.log(1, isNumeric(1) === true);
console.log(1234567890, isNumeric(1234567890) === true);
console.log('1234567890', isNumeric('1234567890') === true);
console.log('0', isNumeric('0') === true);
console.log('1', isNumeric('1') === true);
console.log('1.1', isNumeric('1.1') === true);
console.log('-1', isNumeric('-1') === true);
console.log('-1.2354', isNumeric('-1.2354') === true);
console.log('-1234567890', isNumeric('-1234567890') === true);
console.log(-1, isNumeric(-1) === true);
console.log(-32.1, isNumeric(-32.1) === true);
console.log('0x1', isNumeric('0x1') === true);  // Valid number in hex
// Negative Cases
console.log(true, isNumeric(true) === false);
console.log(false, isNumeric(false) === false);
console.log('1..1', isNumeric('1..1') === false);
console.log('1,1', isNumeric('1,1') === false);
console.log('-32.1.12', isNumeric('-32.1.12') === false);
console.log('[blank]', isNumeric('') === false);
console.log('[spaces]', isNumeric('   ') === false);
console.log('null', isNumeric(null) === false);
console.log('undefined', isNumeric(undefined) === false);
console.log([], isNumeric([]) === false);
console.log('NaN', isNumeric(NaN) === false);

您也可以尝试自己的 isNumeric 函数,然后在这些用例中过去并扫描“对他们所有人来说都是如此。

或者,要查看每个返回的值:

针对 <code>isNumeric()</code> 每次测试的结果

2019: Including ES3, ES6 and TypeScript Examples

Maybe this has been rehashed too many times, however I fought with this one today too and wanted to post my answer, as I didn't see any other answer that does it as simply or thoroughly:

ES3

var isNumeric = function(num){
    return (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);  
}

ES6

const isNumeric = (num) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);

Typescript

const isNumeric = (num: any) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num as number);

This seems quite simple and covers all the bases I saw on the many other posts and thought up myself:

// Positive Cases
console.log(0, isNumeric(0) === true);
console.log(1, isNumeric(1) === true);
console.log(1234567890, isNumeric(1234567890) === true);
console.log('1234567890', isNumeric('1234567890') === true);
console.log('0', isNumeric('0') === true);
console.log('1', isNumeric('1') === true);
console.log('1.1', isNumeric('1.1') === true);
console.log('-1', isNumeric('-1') === true);
console.log('-1.2354', isNumeric('-1.2354') === true);
console.log('-1234567890', isNumeric('-1234567890') === true);
console.log(-1, isNumeric(-1) === true);
console.log(-32.1, isNumeric(-32.1) === true);
console.log('0x1', isNumeric('0x1') === true);  // Valid number in hex
// Negative Cases
console.log(true, isNumeric(true) === false);
console.log(false, isNumeric(false) === false);
console.log('1..1', isNumeric('1..1') === false);
console.log('1,1', isNumeric('1,1') === false);
console.log('-32.1.12', isNumeric('-32.1.12') === false);
console.log('[blank]', isNumeric('') === false);
console.log('[spaces]', isNumeric('   ') === false);
console.log('null', isNumeric(null) === false);
console.log('undefined', isNumeric(undefined) === false);
console.log([], isNumeric([]) === false);
console.log('NaN', isNumeric(NaN) === false);

You can also try your own isNumeric function and just past in these use cases and scan for "true" for all of them.

Or, to see the values that each return:

Results of each test against <code>isNumeric()</code>

叹倦 2024-07-13 10:00:20

TL;DR

这很大程度上取决于您想要将什么解析为数字。

内置函数之间的比较

由于现有的资源都不能满足我的需求,我试图弄清楚这些函数到底发生了什么。

这个问题的三个直接答案感觉就像:

  1. !isNaN(input) (它提供与 +input === +input 相同的输出)
  2. !isNaN(parseFloat (input))
  3. isFinite(input)

但是它们中的任何一个在每种场景中都是正确的吗?

我在几种情况下测试了这些函数,并以降价形式生成输出。 它看起来像这样:

input!isNaN(input)
+input===+input
!isNaN (
parseFloat(
输入))
isFinite(
输入)
评论
123✔️✔️✔️-
'123'✔️✔️✔️-
12.3✔️✔️✔️-
'12.3'✔️✔️✔️-
'     12.3   '✔️✔️✔️空的空白被修剪,如预期的那样。
1_000_000✔️✔️✔️数字分隔符已理解,也是预期的。
“1_000_000❌✔️❌惊喜! JS 只是不会解析字符串内的数字分隔符。 有关详细信息,请查看问题。 (为什么解析为 float 有效?嗯,它没有。

TL;DR

It depends largely on what you want to parse as a number.

Comparison Between Built-in Functions

As none of the existing sources satisfied my soul, I tried to figure out what actually was happening with these functions.

Three immediate answers to this question felt like:

  1. !isNaN(input) (which gives the same output as +input === +input)
  2. !isNaN(parseFloat(input))
  3. isFinite(input)

But are any of them correct in every scenario?

I tested these functions in several cases, and generated output as markdown. This is what it looks like:

input!isNaN(input) or
+input===+input
!isNaN(
parseFloat(
input))
isFinite(
input)
Comment
123✔️✔️✔️-
'123'✔️✔️✔️-
12.3✔️✔️✔️-
'12.3'✔️✔️✔️-
'   12.3   '✔️✔️✔️Empty whitespace trimmed, as expected.
1_000_000✔️✔️✔️Numeric separator understood, also expected.
'1_000_000'✔️Surprise! JS just won't parse numeric separator inside a string. For details, check this issue. (Why then parsing as float worked though? Well, it didn't. ????)
'0b11111111'✔️✔️✔️Binary form understood, as it should've.
'0o377'✔️✔️✔️Octal form understood too.
'0xFF'✔️✔️✔️Of course hex is understood. Did anybody think otherwise? ????
''✔️✔️Should empty string be a number?
'    '✔️✔️Should a whitespace-only string be a number?
'abc'Everybody agrees, not a number.
'12.34Ab!@#$'✔️Ah! Now it's quite understandable what parseFloat() does. Not impressive to me, but may come handy in certain cases.
'10e100'✔️✔️✔️10100 is a number indeed.
But caution! It's way more larger than the maximum safe integer value 253 (about 9×1015). Read this for details.
'10e1000'✔️✔️Say with me, help!
Though not as crazy as it may seem. In JavaScript, a value larger than ~10308 is rounded to infinity, that's why. Look here for details.
And yes, isNaN() considers infinity as a number, and parseFloat() parses infinity as infinity.
null✔️✔️Now this is awkward. In JS, when a conversion is needed, null becomes zero, and we get a finite number.
Then why parseFloat(null) should return a NaN here? Someone please explain this design concept to me.
undefinedAs expected.
Infinity✔️✔️As explained before, isNaN() considers infinity as a number, and parseFloat() parses infinity as infinity.

So...which of them is "correct"?

Should be clear by now, it depends largely on what we need. For example, we may want to consider a null input as 0. In that case isFinite() will work fine.

Again, perhaps we will take a little help from isNaN() when 1010000000000 is needed to be considered a valid number (although the question remains—why would it be, and how would we handle that)!

Of course, we can manually exclude any of the scenarios.

Like in my case, I needed exactly the outputs of isFinite(), except for the null case, the empty string case, and the whitespace-only string case. Also I had no headache about really huge numbers. So my code looked like this:

/**
 * My necessity was met by the following code.
 */

if (input === null) {
    // Null input
} else if (input.trim() === '') {
    // Empty or whitespace-only string
} else if (isFinite(input)) {
    // Input is a number
} else {
    // Not a number
}

And also, this was my JavaScript to generate the table:

/**
 * Note: JavaScript does not print numeric separator inside a number.
 * In that single case, the markdown output was manually corrected.
 * Also, the comments were manually added later, of course.
 */

let inputs = [
    123, '123', 12.3, '12.3', '   12.3   ',
    1_000_000, '1_000_000',
    '0b11111111', '0o377', '0xFF',
    '', '    ',
    'abc', '12.34Ab!@#
,
    '10e100', '10e1000',
    null, undefined, Infinity];

let markdownOutput = `| \`input\` | \`!isNaN(input)\` or <br>\`+input === +input\` | \`!isNaN(parseFloat(input))\` | \`isFinite(input)\` | Comment |
| :---: | :---: | :---: | :---: | :--- |\n`;

for (let input of inputs) {
    let outputs = [];
    outputs.push(!isNaN(input));
    outputs.push(!isNaN(parseFloat(input)));
    outputs.push(isFinite(input));

    if (typeof input === 'string') {
        // Output with quotations
        console.log(`'${input}'`);
        markdownOutput += `| '${input}'`;
    } else {
        // Output without quotes
        console.log(input);
        markdownOutput += `| ${input}`;
    }

    for (let output of outputs) {
        console.log('\t' + output);
        if (output === true) {
            markdownOutput += ` | <div style="color:limegreen">true</div>`;
            // markdownOutput += ` | ✔️`; // for stackoverflow
        } else {
            markdownOutput += ` | <div style="color:orangered">false</div>`;
            // markdownOutput += ` | ❌`; // for stackoverflow
        }
    }

    markdownOutput += ` ||\n`;
}

// Replace two or more whitespaces with $nbsp;
markdownOutput = markdownOutput.replaceAll(`  `, `  `);

// Print markdown to console
console.log(markdownOutput);
又爬满兰若 2024-07-13 10:00:20

尝试使用 isNan 函数

isNaN() 函数判断一个值是否为非法数字(Not-a-Number)。

如果该值等于 NaN,则该函数返回 true。 否则返回 false。

此函数与特定于 Number 的函数不同 Number.isNaN() 方法。

  全局 isNaN() 函数,将测试值转换为 Number,然后进行测试。

Number.isNan() 不会将值转换为 Number,并且对于任何非 Number 类型的值都不会返回 true...

Try the isNan function:

The isNaN() function determines whether a value is an illegal number (Not-a-Number).

This function returns true if the value equates to NaN. Otherwise it returns false.

This function is different from the Number specific Number.isNaN() method.

  The global isNaN() function, converts the tested value to a Number, then tests it.

Number.isNan() does not convert the values to a Number, and will not return true for any value that is not of the type Number...

风和你 2024-07-13 10:00:20

JavaScript 全局 isFinite()检查值是否是有效(有限)数字。

请参阅 MDN,了解 Number 之间的差异.isFinite() 和全局 isFinite()

let a = isFinite('abc') // false
let b = isFinite('123') // true
let c = isFinite('12a') // false
let d = isFinite(null)  // true
console.log(a, b, c, d)

The JavaScript global isFinite() checks if a value is a valid (finite) number.

See MDN for the difference between Number.isFinite() and global isFinite().

let a = isFinite('abc') // false
let b = isFinite('123') // true
let c = isFinite('12a') // false
let d = isFinite(null)  // true
console.log(a, b, c, d)

萌化 2024-07-13 10:00:20

老问题,但给出的答案中缺少几点。

科学记数法。

!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 位(省略前导零后)。

Infinity

> 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);
  }

然而,即使这个版本也远未完成。 这里不处理前导零,但它们确实会影响长度测试。

Old question, but there are several points missing in the given answers.

Scientific notation.

!isNaN('1e+30') is true, however in most of the cases when people ask for numbers, they do not want to match things like 1e+30.

Large floating numbers may behave weird

Observe (using 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
>

On the other hand:

> 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
>

So, if one expects String(Number(s)) === s, then better limit your strings to 15 digits at most (after omitting leading zeros).

Infinity

> typeof Infinity
'number'
> !isNaN('Infinity')
true
> isFinite('Infinity')
false
>

Given all that, checking that the given string is a number satisfying all of the following:

  • non scientific notation
  • predictable conversion to Number and back to String
  • finite

is not such an easy task. Here is a simple version:

  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);
  }

However, even this one is far from complete. Leading zeros are not handled here, but they do screw the length test.

七颜 2024-07-13 10:00:20

有人也可能从基于正则表达式的答案中受益。 如下:

Oneliner isInteger:

const isInteger = num => /^-?[0-9]+$/.test(num+'');

Oneliner isNumeric: 接受整数和小数

const isNumeric = num => /^-?[0-9]+(?:\.[0-9]+)?$/.test(num+'');

Someone may also benefit from a regex based answer. Here it is:

One liner isInteger:

const isInteger = num => /^-?[0-9]+$/.test(num+'');

One liner isNumeric: Accepts integers and decimals

const isNumeric = num => /^-?[0-9]+(?:\.[0-9]+)?$/.test(num+'');
花间憩 2024-07-13 10:00:20

我已经测试过,迈克尔的解决方案是最好的。 为他上面的答案投票(在本页搜索“如果你真的想确保一个字符串”来找到它)。 本质上,他的答案是这样的:

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, [] (还有其他?)

I have tested and Michael's solution is best. Vote for his answer above (search this page for "If you really want to make sure that a string" to find it). In essence, his answer is this:

function isNumeric(num){
  num = "" + num; //coerce num to be a string
  return !isNaN(num) && !isNaN(parseFloat(num));
}

It works for every test case, which I documented here:
https://jsfiddle.net/wggehvp9/5/

Many of the other solutions fail for these edge cases:
' ', null, "", true, and [].
In theory, you could use them, with proper error handling, for example:

return !isNaN(num);

or

return (+num === +num);

with special handling for
/\s/, null, "", true, false, [] (and others?)

苏璃陌 2024-07-13 10:00:20

您可以在传递时使用 Number 的结果其构造函数的参数。

如果参数(字符串)无法转换为数字,则返回 NaN,因此您可以确定提供的字符串是否为有效数字。

注意:注意当传递空字符串或'\t\t''\n\t'作为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

You can use the result of Number when passing an argument to its constructor.

If the argument (a string) cannot be converted into a number, it returns NaN, so you can determinate if the string provided was a valid number or not.

Notes: Note when passing empty string or '\t\t' and '\n\t' as Number will return 0; Passing true will return 1 and false returns 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
苄①跕圉湢 2024-07-13 10:00:20

也许有一两个人遇到这个问题,需要比平时更严格检查(就像我一样)。 在这种情况下,这可能会有用:

if(str === String(Number(str))) {
  // it's a "perfectly formatted" number
}

小心! 这将拒绝 .140.00008000.1 等字符串。 它非常挑剔 - 字符串必须与数字的“最小完美形式”匹配才能通过此测试。

它使用 StringNumber 构造函数将字符串转换为数字并再次转换回来,从而检查 JavaScript 引擎的“完美最小形式”(它转换为的形式)是否与初始 Number 构造函数)匹配原始字符串。

Maybe there are one or two people coming across this question who need a much stricter check than usual (like I did). In that case, this might be useful:

if(str === String(Number(str))) {
  // it's a "perfectly formatted" number
}

Beware! This will reject strings like .1, 40.000, 080, 00.1. It's very picky - the string must match the "most minimal perfect form" of the number for this test to pass.

It uses the String and Number constructor to cast the string to a number and back again and thus checks if the JavaScript engine's "perfect minimal form" (the one it got converted to with the initial Number constructor) matches the original string.

喜你已久 2024-07-13 10:00:20

我喜欢这种简单性。

Number.isNaN(Number(value))

上面是常规的 Javascript,但我将其与打字稿结合使用 typeguard< /a> 用于智能类型检查。 这对于打字稿编译器非常有用,可以为您提供正确的智能感知,并且没有类型错误。

Typescript typeguards

警告:请参阅下面 Jeremy 的评论。这对某些值有一些问题,我现在没有时间修复它,但是使用 typescript typeguard 的想法很有用,所以我不会删除此部分。

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 | 字符串。 您可能想要根据它是否是字符串来执行逻辑。

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 足够智能,可以将 if 语句中的 width 类型限制为仅 string。 这允许编译器允许 width.endsWith(...) ,如果类型是 string | 则不允许。 号码。

您可以将 typeguard 称为任何您想要的 isNotNumberisNumberisStringisNotString 但我认为 isString 有点含糊并且难以阅读。

I like the simplicity of this.

Number.isNaN(Number(value))

The above is regular Javascript, but I'm using this in conjunction with a typescript typeguard for smart type checking. This is very useful for the typescript compiler to give you correct intellisense, and no type errors.

Typescript typeguards

Warning: See Jeremy's comment below. This has some issues with certain values and I don't have time to fix it now, but the idea of using a typescript typeguard is useful so I won't delete this section.

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;
}

Let's say you have a property width which is number | string. You may want to do logic based on whether or not it's a 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;    
}

The typeguard is smart enough to constrain the type of width within the if statement to be ONLY string. This permits the compiler to allow width.endsWith(...) which it wouldn't allow if the type was string | number.

You can call the typeguard whatever you want isNotNumber, isNumber, isString, isNotString but I think isString is kind of ambiguous and harder to read.

清音悠歌 2024-07-13 10:00:20

为什么 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 的答案制成的装置,对前导/尾随空格进行了额外检查(因为 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));
};

我还没有对其中任何一个进行太多测试,除了手动测试我将在当前困境中遇到的少数用例之外,其他方式都是非常标准的东西。 这是一种“站在巨人肩膀上”的局面。

Why is jQuery's implementation not good enough?

function isNumeric(a) {
    var b = a && a.toString();
    return !$.isArray(a) && b - parseFloat(b) + 1 >= 0;
};

Michael suggested something like this (although I've stolen "user1691651 - John"'s altered version here):

function isNumeric(num){
    num = "" + num; //coerce num to be a string
    return !isNaN(num) && !isNaN(parseFloat(num));
}

The following is a solution with most likely bad performance, but solid results. It is a contraption made from the jQuery 1.12.4 implementation and Michael's answer, with an extra check for leading/trailing spaces (because Michael's version returns true for numerics with leading/trailing spaces):

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));
};

The latter version has two new variables, though. One could get around one of those, by doing:

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));
};

I haven't tested any of these very much, by other means than manually testing the few use-cases I'll be hitting with my current predicament, which is all very standard stuff. This is a "standing-on-the-shoulders-of-giants" situation.

初懵 2024-07-13 10:00:20

2019:实用且严格的数字有效性检查

通常,“有效数字”是指不包括 NaN 和 Infinity 的 Javascript 数字,即“有限数字”。

要检查值的数字有效性(例如来自外部源),您可以在 ESlint Airbnb 样式中定义:

/**
 * Returns true if 'candidate' is a finite number or a string referring (not just 'including') a finite number
 * To keep in mind:
 *   Number(true) = 1
 *   Number('') = 0
 *   Number("   10  ") = 10
 *   !isNaN(true) = true
 *   parseFloat('10 a') = 10
 *
 * @param {?} candidate
 * @return {boolean}
 */
function isReferringFiniteNumber(candidate) {
  if (typeof (candidate) === 'number') return Number.isFinite(candidate);
  if (typeof (candidate) === 'string') {
    return (candidate.trim() !== '') && Number.isFinite(Number(candidate));
  }
  return false;
}

并以这种方式使用它:

if (isReferringFiniteNumber(theirValue)) {
  myCheckedValue = Number(theirValue);
} else {
  console.warn('The provided value doesn\'t refer to a finite number');
}

2019: Practical and tight numerical validity check

Often, a 'valid number' means a Javascript number excluding NaN and Infinity, ie a 'finite number'.

To check the numerical validity of a value (from an external source for example), you can define in ESlint Airbnb style :

/**
 * Returns true if 'candidate' is a finite number or a string referring (not just 'including') a finite number
 * To keep in mind:
 *   Number(true) = 1
 *   Number('') = 0
 *   Number("   10  ") = 10
 *   !isNaN(true) = true
 *   parseFloat('10 a') = 10
 *
 * @param {?} candidate
 * @return {boolean}
 */
function isReferringFiniteNumber(candidate) {
  if (typeof (candidate) === 'number') return Number.isFinite(candidate);
  if (typeof (candidate) === 'string') {
    return (candidate.trim() !== '') && Number.isFinite(Number(candidate));
  }
  return false;
}

and use it this way:

if (isReferringFiniteNumber(theirValue)) {
  myCheckedValue = Number(theirValue);
} else {
  console.warn('The provided value doesn\'t refer to a finite number');
}
少女情怀诗 2024-07-13 10:00:20

它对于 TypeScript 无效,如下所示:

declare function isNaN(number: number): boolean;

对于 TypeScript,您可以使用:

/^\d+$/.test(key)

It is not valid for TypeScript as:

declare function isNaN(number: number): boolean;

For TypeScript you can use:

/^\d+$/.test(key)

不一样的天空 2024-07-13 10:00:20

parseInt(),但请注意该函数有点不同,例如它为 parseInt("100px") 返回 100。

parseInt(), but be aware that this function is a bit different in the sense that it for example returns 100 for parseInt("100px").

避讳 2024-07-13 10:00:20

引用:

isNaN(num) // 如果变量不包含有效数字,则返回 true

如果您需要检查前导/尾随空格,则不完全为 true - 例如,当需要一定数量的数字时,您需要获取,例如、“1111”,而不是“111”或“111”,可能是 PIN 输入。

更好地使用:

var num = /^\d+$/.test(num)

Quote:

isNaN(num) // returns true if the variable does NOT contain a valid number

is not entirely true if you need to check for leading/trailing spaces - for example when a certain quantity of digits is required, and you need to get, say, '1111' and not ' 111' or '111 ' for perhaps a PIN input.

Better to use:

var num = /^\d+$/.test(num)
七秒鱼° 2024-07-13 10:00:20

当防范空字符串和 null

// Base cases that are handled properly
Number.isNaN(Number('1')); // => false
Number.isNaN(Number('-1')); // => false
Number.isNaN(Number('1.1')); // => false
Number.isNaN(Number('-1.1')); // => false
Number.isNaN(Number('asdf')); // => true
Number.isNaN(Number(undefined)); // => true

// Special notation cases that are handled properly
Number.isNaN(Number('1e1')); // => false
Number.isNaN(Number('1e-1')); // => false
Number.isNaN(Number('-1e1')); // => false
Number.isNaN(Number('-1e-1')); // => false
Number.isNaN(Number('0b1')); // => false
Number.isNaN(Number('0o1')); // => false
Number.isNaN(Number('0xa')); // => false

// Edge cases that will FAIL if not guarded against
Number.isNaN(Number('')); // => false
Number.isNaN(Number(' ')); // => false
Number.isNaN(Number(null)); // => false

// Edge cases that are debatable
Number.isNaN(Number('-0b1')); // => true
Number.isNaN(Number('-0o1')); // => true
Number.isNaN(Number('-0xa')); // => true
Number.isNaN(Number('Infinity')); // => false 
Number.isNaN(Number('INFINITY')); // => true  
Number.isNaN(Number('-Infinity')); // => false 
Number.isNaN(Number('-INFINITY')); // => true  

当不防范空字符串和 null

使用 parseInt:

// Base cases that are handled properly
Number.isNaN(parseInt('1')); // => false
Number.isNaN(parseInt('-1')); // => false
Number.isNaN(parseInt('1.1')); // => false
Number.isNaN(parseInt('-1.1')); // => false
Number.isNaN(parseInt('asdf')); // => true
Number.isNaN(parseInt(undefined)); // => true
Number.isNaN(parseInt('')); // => true
Number.isNaN(parseInt(' ')); // => true
Number.isNaN(parseInt(null)); // => true

// Special notation cases that are handled properly
Number.isNaN(parseInt('1e1')); // => false
Number.isNaN(parseInt('1e-1')); // => false
Number.isNaN(parseInt('-1e1')); // => false
Number.isNaN(parseInt('-1e-1')); // => false
Number.isNaN(parseInt('0b1')); // => false
Number.isNaN(parseInt('0o1')); // => false
Number.isNaN(parseInt('0xa')); // => false

// Edge cases that are debatable
Number.isNaN(parseInt('-0b1')); // => false
Number.isNaN(parseInt('-0o1')); // => false
Number.isNaN(parseInt('-0xa')); // => false
Number.isNaN(parseInt('Infinity')); // => true 
Number.isNaN(parseInt('INFINITY')); // => true  
Number.isNaN(parseInt('-Infinity')); // => true 
Number.isNaN(parseInt('-INFINITY')); // => true 

使用 parseFloat

// Base cases that are handled properly
Number.isNaN(parseFloat('1')); // => false
Number.isNaN(parseFloat('-1')); // => false
Number.isNaN(parseFloat('1.1')); // => false
Number.isNaN(parseFloat('-1.1')); // => false
Number.isNaN(parseFloat('asdf')); // => true
Number.isNaN(parseFloat(undefined)); // => true
Number.isNaN(parseFloat('')); // => true
Number.isNaN(parseFloat(' ')); // => true
Number.isNaN(parseFloat(null)); // => true

// Special notation cases that are handled properly
Number.isNaN(parseFloat('1e1')); // => false
Number.isNaN(parseFloat('1e-1')); // => false
Number.isNaN(parseFloat('-1e1')); // => false
Number.isNaN(parseFloat('-1e-1')); // => false
Number.isNaN(parseFloat('0b1')); // => false
Number.isNaN(parseFloat('0o1')); // => false
Number.isNaN(parseFloat('0xa')); // => false

// Edge cases that are debatable
Number.isNaN(parseFloat('-0b1')); // => false
Number.isNaN(parseFloat('-0o1')); // => false
Number.isNaN(parseFloat('-0xa')); // => false
Number.isNaN(parseFloat('Infinity')); // => false 
Number.isNaN(parseFloat('INFINITY')); // => true  
Number.isNaN(parseFloat('-Infinity')); // => false 
Number.isNaN(parseFloat('-INFINITY')); // => true

注释:

  • 仅考虑字符串、空和未初始化的值,以与解决原始问题保持一致。 如果考虑的值是数组和对象,则存在其他边缘情况。
  • 二进制、八进制、十六进制和指数表示法中的字符不区分大小写(即:“0xFF”、“0XFF”、“0xfF”) ' 等在上面显示的测试用例中都会产生相同的结果)。
  • Infinity(区分大小写)不同,在某些情况下,Number 中的常量以字符串格式作为测试用例传递给上述任何方法的Math 对象将被确定为不是数字。
  • 参见 此处了解如何将参数转换为 Number 以及为什么存在 null 和空字符串的边缘情况。

When guarding against empty strings and null

// Base cases that are handled properly
Number.isNaN(Number('1')); // => false
Number.isNaN(Number('-1')); // => false
Number.isNaN(Number('1.1')); // => false
Number.isNaN(Number('-1.1')); // => false
Number.isNaN(Number('asdf')); // => true
Number.isNaN(Number(undefined)); // => true

// Special notation cases that are handled properly
Number.isNaN(Number('1e1')); // => false
Number.isNaN(Number('1e-1')); // => false
Number.isNaN(Number('-1e1')); // => false
Number.isNaN(Number('-1e-1')); // => false
Number.isNaN(Number('0b1')); // => false
Number.isNaN(Number('0o1')); // => false
Number.isNaN(Number('0xa')); // => false

// Edge cases that will FAIL if not guarded against
Number.isNaN(Number('')); // => false
Number.isNaN(Number(' ')); // => false
Number.isNaN(Number(null)); // => false

// Edge cases that are debatable
Number.isNaN(Number('-0b1')); // => true
Number.isNaN(Number('-0o1')); // => true
Number.isNaN(Number('-0xa')); // => true
Number.isNaN(Number('Infinity')); // => false 
Number.isNaN(Number('INFINITY')); // => true  
Number.isNaN(Number('-Infinity')); // => false 
Number.isNaN(Number('-INFINITY')); // => true  

When NOT guarding against empty strings and null

Using parseInt:

// Base cases that are handled properly
Number.isNaN(parseInt('1')); // => false
Number.isNaN(parseInt('-1')); // => false
Number.isNaN(parseInt('1.1')); // => false
Number.isNaN(parseInt('-1.1')); // => false
Number.isNaN(parseInt('asdf')); // => true
Number.isNaN(parseInt(undefined)); // => true
Number.isNaN(parseInt('')); // => true
Number.isNaN(parseInt(' ')); // => true
Number.isNaN(parseInt(null)); // => true

// Special notation cases that are handled properly
Number.isNaN(parseInt('1e1')); // => false
Number.isNaN(parseInt('1e-1')); // => false
Number.isNaN(parseInt('-1e1')); // => false
Number.isNaN(parseInt('-1e-1')); // => false
Number.isNaN(parseInt('0b1')); // => false
Number.isNaN(parseInt('0o1')); // => false
Number.isNaN(parseInt('0xa')); // => false

// Edge cases that are debatable
Number.isNaN(parseInt('-0b1')); // => false
Number.isNaN(parseInt('-0o1')); // => false
Number.isNaN(parseInt('-0xa')); // => false
Number.isNaN(parseInt('Infinity')); // => true 
Number.isNaN(parseInt('INFINITY')); // => true  
Number.isNaN(parseInt('-Infinity')); // => true 
Number.isNaN(parseInt('-INFINITY')); // => true 

Using parseFloat:

// Base cases that are handled properly
Number.isNaN(parseFloat('1')); // => false
Number.isNaN(parseFloat('-1')); // => false
Number.isNaN(parseFloat('1.1')); // => false
Number.isNaN(parseFloat('-1.1')); // => false
Number.isNaN(parseFloat('asdf')); // => true
Number.isNaN(parseFloat(undefined)); // => true
Number.isNaN(parseFloat('')); // => true
Number.isNaN(parseFloat(' ')); // => true
Number.isNaN(parseFloat(null)); // => true

// Special notation cases that are handled properly
Number.isNaN(parseFloat('1e1')); // => false
Number.isNaN(parseFloat('1e-1')); // => false
Number.isNaN(parseFloat('-1e1')); // => false
Number.isNaN(parseFloat('-1e-1')); // => false
Number.isNaN(parseFloat('0b1')); // => false
Number.isNaN(parseFloat('0o1')); // => false
Number.isNaN(parseFloat('0xa')); // => false

// Edge cases that are debatable
Number.isNaN(parseFloat('-0b1')); // => false
Number.isNaN(parseFloat('-0o1')); // => false
Number.isNaN(parseFloat('-0xa')); // => false
Number.isNaN(parseFloat('Infinity')); // => false 
Number.isNaN(parseFloat('INFINITY')); // => true  
Number.isNaN(parseFloat('-Infinity')); // => false 
Number.isNaN(parseFloat('-INFINITY')); // => true

Notes:

  • Only string, empty, and uninitialized values are considered in keeping with addressing the original question. Additional edge cases exist if arrays and objects are the values being considered.
  • Characters in binary, octal, hexadecimal, and exponential notation are not case-sensitive (ie: '0xFF', '0XFF', '0xfF' etc. will all yield the same result in the test cases shown above).
  • Unlike with Infinity (case-sensitive) in some cases, constants from the Number and Math objects passed as test cases in string format to any of the methods above will be determined to not be numbers.
  • See here for an explanation of how arguments are converted to a Number and why the edge cases for null and empty strings exist.
怪我闹别瞎闹 2024-07-13 10:00:20

这样对我有用。

function isNumeric(num){
    let value1 = num.toString();
    let value2 = parseFloat(num).toString();
    return (value1 === value2);
}

console.log(
    isNumeric(123),     //true
    isNumeric(-123),    //true
    isNumeric('123'),   //true
    isNumeric('-123'),  //true
    isNumeric(12.2),    //true
    isNumeric(-12.2),   //true
    isNumeric('12.2'),  //true
    isNumeric('-12.2'), //true
    isNumeric('a123'),  //false
    isNumeric('123a'),  //false
    isNumeric(' 123'),  //false
    isNumeric('123 '),  //false
    isNumeric('a12.2'), //false
    isNumeric('12.2a'), //false
    isNumeric(' 12.2'), //false
    isNumeric('12.2 '), //false
)

This way it works for me.

function isNumeric(num){
    let value1 = num.toString();
    let value2 = parseFloat(num).toString();
    return (value1 === value2);
}

console.log(
    isNumeric(123),     //true
    isNumeric(-123),    //true
    isNumeric('123'),   //true
    isNumeric('-123'),  //true
    isNumeric(12.2),    //true
    isNumeric(-12.2),   //true
    isNumeric('12.2'),  //true
    isNumeric('-12.2'), //true
    isNumeric('a123'),  //false
    isNumeric('123a'),  //false
    isNumeric(' 123'),  //false
    isNumeric('123 '),  //false
    isNumeric('a12.2'), //false
    isNumeric('12.2a'), //false
    isNumeric(' 12.2'), //false
    isNumeric('12.2 '), //false
)
楠木可依 2024-07-13 10:00:20

这是一个相当老的问题,但第一个出现的问题是谷歌搜索,通读答案后发现有很多混乱,而且 Node 在处理数字时非常混乱......

很多答案都很好,对于大多数情况来说可能已经足够好了,但我试图利用所有的“陷阱”并提出一个“安全”的解决方案来覆盖所有指出的区域,以及我想出的(不是那么简单的)解决方案是:

const isNum = (num) => typeof num !== 'object' && (!Number.isNaN(+(String((String(num) || '').replace(/[^0-9\.\-e]/, '') !== String(num) || num === '' ? NaN : num))));

这适用于我在此线程中找到的大多数情况:

isNum('n') // false
isNum('') // false
isNum('\t') // false
isNum('\r\n what?') // false
isNum(null) // false
isnum(undefined) // false
isnum(NaN) // false

isNum(0) // true
isNum('0') // true
isNum(-0) // true
isNum('1.23') // true
isNum(1.23) // true
isNum(4.917736942280289e-10) // true
isNum(BigInt("0b11111111111111111111111111111111111111111111111111111")) // true
isNum(0b11111111111111111111111111111111111111111111111111111) // true

编辑:当我们决定开始在我们公司的全球范围内使用它时,我将其作为 npm 包发布给任何感兴趣的人:

const { isNum } = require('@qvalia/isnum');

console.log(`isNum('abc')=${isNum('abc')}`);

This is a fairly old question, but the first that turns up Googling, and having read through the answers there is a lot of confusion, and Node is very confusing when it comes to handling numbers...

A lot of the answers are good, and probably good enough for most cases, but I tried to leverage all of the "pit falls" and come up with a "safe" solution that would cover all the pointed out areas, and the (not so simple) solution I came up with is:

const isNum = (num) => typeof num !== 'object' && (!Number.isNaN(+(String((String(num) || '').replace(/[^0-9\.\-e]/, '') !== String(num) || num === '' ? NaN : num))));

This will work with most cases I found in this thread:

isNum('n') // false
isNum('') // false
isNum('\t') // false
isNum('\r\n what?') // false
isNum(null) // false
isnum(undefined) // false
isnum(NaN) // false

isNum(0) // true
isNum('0') // true
isNum(-0) // true
isNum('1.23') // true
isNum(1.23) // true
isNum(4.917736942280289e-10) // true
isNum(BigInt("0b11111111111111111111111111111111111111111111111111111")) // true
isNum(0b11111111111111111111111111111111111111111111111111111) // true

EDIT: As we decided to start using this globally in our company, I published it as an npm package for anyone interested:

const { isNum } = require('@qvalia/isnum');

console.log(`isNum('abc')=${isNum('abc')}`);
暮年慕年 2024-07-13 10:00:20

这是建立在之前的一些答案和评论的基础上的。 它涵盖了所有边缘情况,还可以选择处理科学记数法:

const NUMBER_REG_EXP = /^-?\d+(?:\.\d+)?$/;
const SCIENTIFIC_NOTATION_REG_EXP = /^-?\d+(?:\.\d+)?(?:[eE]\d+)?$/;

const isNumeric = (n, allowScientificNotation = false) => (
    (typeof n === 'number' && !Number.isNaN(n)) || 
    (typeof n === 'string' && (allowScientificNotation ?
        SCIENTIFIC_NOTATION_REG_EXP : NUMBER_REG_EXP).test(n))
);

This is built on some of the previous answers and comments. It covers all the edge cases and also handles scientific notation optionally:

const NUMBER_REG_EXP = /^-?\d+(?:\.\d+)?$/;
const SCIENTIFIC_NOTATION_REG_EXP = /^-?\d+(?:\.\d+)?(?:[eE]\d+)?$/;

const isNumeric = (n, allowScientificNotation = false) => (
    (typeof n === 'number' && !Number.isNaN(n)) || 
    (typeof n === 'string' && (allowScientificNotation ?
        SCIENTIFIC_NOTATION_REG_EXP : NUMBER_REG_EXP).test(n))
);
深海蓝天 2024-07-13 10:00:20

如果有人陷入如此困境,我花了一些时间尝试修补 moment.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

欢迎任何建议。 :]

If anyone ever gets this far down, I spent some time hacking on this trying to patch moment.js (https://github.com/moment/moment). Here's something that I took away from it:

function isNumeric(val) {
    var _val = +val;
    return (val !== val + 1) //infinity check
        && (_val === +val) //Cute coercion check
        && (typeof val !== 'object') //Array/object check
}

Handles the following cases:

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()))

Ironically, the one I am struggling with the most:

isNumeric(new Number(1)) => false

Any suggestions welcome. :]

疏忽 2024-07-13 10:00:20

我最近写了一篇关于如何确保变量是有效数字的文章: https://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.md 本文解释了如何确保浮点或整数(如果这很重要)(+x~~x)。

本文假设变量首先是一个字符串或数字,并且修剪可用/填充。 扩展它来处理其他类型也不难。 这是它的核心内容:

// 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
}

I recently wrote an article about ways to ensure a variable is a valid number: https://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.md The article explains how to ensure floating point or integer, if that's important (+x vs ~~x).

The article assumes the variable is a string or a number to begin with and trim is available/polyfilled. It wouldn't be hard to extend it to handle other types, as well. Here's the meat of it:

// 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
}
ζ澈沫 2024-07-13 10:00:20

省去尝试寻找“内置”解决方案的麻烦。

没有一个好的答案,并且该线程中获得大力支持的答案是错误的。

npm install is-number

在 JavaScript 中,可靠地检查值是否为数字并不总是那么简单。 开发人员通常使用 +、- 或 Number() 将字符串值转换为数字(例如,当从用户输入、正则表达式匹配、解析器等返回值时)。 但有许多非直观的边缘情况会产生意想不到的结果:

console.log(+[]); //=> 0
console.log(+''); //=> 0
console.log(+'   '); //=> 0
console.log(typeof NaN); //=> 'number'

Save yourself the headache of trying to find a "built-in" solution.

There isn't a good answer, and the hugely upvoted answer in this thread is wrong.

npm install is-number

In JavaScript, it's not always as straightforward as it should be to reliably check if a value is a number. It's common for devs to use +, -, or Number() to cast a string value to a number (for example, when values are returned from user input, regex matches, parsers, etc). But there are many non-intuitive edge cases that yield unexpected results:

console.log(+[]); //=> 0
console.log(+''); //=> 0
console.log(+'   '); //=> 0
console.log(typeof NaN); //=> 'number'
梦年海沫深 2024-07-13 10:00:20
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 ...
}
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 ...
}
与往事干杯 2024-07-13 10:00:20

因此,这取决于您希望它处理的测试用例。

function isNumeric(number) {
  return !isNaN(parseFloat(number)) && !isNaN(+number);
}

我正在寻找的是 javascript 中的常规数字类型。
0、1、-1、1.1、-1.1、1E1、-1E1、1e1、-1e1、0.1e10、-0.1.e10、0xAF1、0o172、Math.PI、Number.NEGATIVE_INFINITY、Number.POSITIVE_INFINITY

而且它们也是字符串的表示:
<代码>“0”、“1”、“-1”、“1.1”、“-1.1”、“1E1”、“-1E1”、“1e1”、“-1e1”、“0.1e10”、“-” 0.1.e10', '0xAF1', '0o172'

我确实想省略并且不将它们标记为数字
'', ' ', [], {}, null, undefined, NaN

截至今天,所有其他答案似乎都未能通过这些测试用例之一。

So, it will depend on the test cases that you want it to handle.

function isNumeric(number) {
  return !isNaN(parseFloat(number)) && !isNaN(+number);
}

What I was looking for was regular types of numbers in javascript.
0, 1 , -1, 1.1 , -1.1 , 1E1 , -1E1 , 1e1 , -1e1, 0.1e10, -0.1.e10 , 0xAF1 , 0o172, Math.PI, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY

And also they're representations as strings:
'0', '1', '-1', '1.1', '-1.1', '1E1', '-1E1', '1e1', '-1e1', '0.1e10', '-0.1.e10', '0xAF1', '0o172'

I did want to leave out and not mark them as numeric
'', ' ', [], {}, null, undefined, NaN

As of today, all other answers seemed to failed one of these test cases.

萌吟 2024-07-13 10:00:20

您还可以使用简单的 parseInt 函数...以及 if 条件
例如

if (parseInt(i)){
    (i in dic) ? dic[i] += 1 : dic[i] = 1
}

You can also use a simple parseInt function too... with an if the condition
for example

if (parseInt(i)){
    (i in dic) ? dic[i] += 1 : dic[i] = 1
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文