簡體   English   中英

如何檢查字符串是否為有效數字?

[英]How can I check if a string is a valid number?

我希望在與舊的 VB6 IsNumeric() function 相同的概念空間中有一些東西?

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

要將包含數字的字符串轉換為數字:

僅當字符串包含數字字符時才有效,否則返回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

如果您只是想檢查一個字符串是否是一個整數(沒有小數位),那么正則表達式是一個不錯的方法。 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

你可以走正則表達式的方式:

var num = "987238";

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

這個問題的公認答案有很多缺陷(正如其他幾個用戶所強調的那樣)。 這是在 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
["

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

試試isNan 函數

isNaN() 函數判斷一個值是否為非法數字(Not-a-Number)。

如果值等於 NaN,則此函數返回 true。 否則返回false。

此函數不同於數字特定的Number.isNaN()方法。

全局 isNaN() 函數,將測試值轉換為數字,然后對其進行測試。

Number.isNan() 不會將值轉換為數字,並且不會為任何非數字類型的值返回 true...

老問題,但在給定的答案中缺少幾點。

科學計數法。

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

然而,即使是這一點也遠未完成。 此處不處理前導零,但它們確實會影響長度測試。

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

打字稿

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> 的每個測試的結果

我已經測試過,邁克爾的解決方案是最好的。 投票給他上面的答案(在此頁面中搜索“如果您真的想確保一個字符串”以找到它)。 本質上,他的回答是這樣的:

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、[](和其他?)進行特殊處理

將參數傳遞給其構造函數時,可以使用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

也許有一兩個遇到這個問題的人需要比平時更嚴格的檢查(就像我一樣)。 在這種情況下,這可能很有用:

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

謹防! 這將拒絕像.1 , 40.000 , 080 , 00.1這樣的字符串。 它非常挑剔 - 字符串必須與該測試通過的數字的“最小完美形式”匹配。

它使用StringNumber構造函數將字符串轉換為數字並再次返回,從而檢查 JavaScript 引擎的“完美最小形式”(它使用初始Number構造函數轉換為的形式)是否與原始字符串匹配。

TL;博士

這在很大程度上取決於要解析為數字的內容。

內置函數比較

由於沒有一個現有的資源能滿足我的靈魂,我試圖弄清楚這些函數到底發生了什么。

這個問題的三個直接答案感覺就像:

  1. !isNaN(input) (提供與+input === +input相同的輸出)
  2. !isNaN(parseFloat(input))
  3. isFinite(input)

但是它們中的任何一個在每種情況下都是正確的嗎?

我在幾個案例中測試了這些函數,並生成了降價輸出。 這是它的樣子:

input !isNaN(input)
+input===+input
!isNaN(
parseFloat(
input))
isFinite(
input)
評論
123 ✔️ ✔️ ✔️ -
'123' ✔️ ✔️ ✔️ -
12.3 ✔️ ✔️ ✔️ -
'12.3' ✔️ ✔️ ✔️ -
'12.3' ✔️ ✔️ ✔️ 正如預期的那樣,修剪了空白。
1_000_000 ✔️ ✔️ ✔️ 數字分隔符可以理解,也可以預期。
'1_000_000' ✔️ 驚喜! JS 只是不會解析字符串中的數字分隔符。 有關詳細信息,請檢查問題。 (為什么然后解析為浮點數?好吧,它沒有。😉)
'0b11111111' ✔️ ✔️ ✔️ 二進制形式理解,因為它應該。
'0o377' ✔️ ✔️ ✔️ 八進制形式也可以理解。
'0xFF' ✔️ ✔️ ✔️ 當然可以理解十六進制。 有人有其他想法嗎? 😒
'' ✔️ ✔️ 空字符串應該是數字嗎?
'' ✔️ ✔️ 只有空格的字符串應該是數字嗎?
'ABC' 每個人都同意,而不是一個數字。
'12.34Ab!@#$' ✔️ 啊! 現在很容易理解parseFloat()的作用了。 對我來說並不令人印象深刻,但在某些情況下可能會派上用場。
'10e100' ✔️ ✔️ ✔️ 10 100確實是一個數字。
但是要小心! 它比最大安全整數值 2 53 (大約 9×10 15 )大得多。 閱讀本文了解詳情。
'10e1000' ✔️ ✔️ 跟我說,救命!
雖然不像看起來那么瘋狂。 在 JavaScript 中,大於 ~10 308的值會四舍五入為無窮大,這就是原因。 在這里查看詳細信息。
是的, isNaN()將無窮大視為一個數字,而parseFloat()將無窮大解析為無窮大。
無效的 ✔️ ✔️ 現在這很尷尬。 在 JS 中,當需要轉換時,null 變為零,我們得到一個有限數。
那么為什么parseFloat(null)應該在這里返回一個NaN呢? 有人請給我解釋一下這個設計概念。
不明確的 正如預期的那樣。
無窮 ✔️ ✔️ 如前所述, isNaN()將無窮大視為一個數字,而parseFloat()將無窮大解析為無窮大。

那么......他們中的哪一個是“正確的”?

現在應該清楚了,這在很大程度上取決於我們需要什么 例如,我們可能希望將空輸入視為 0。在這種情況下, isFinite()可以正常工作。

同樣,當需要將 10 10000000000視為有效數字時,也許我們會從isNaN()中獲得一點幫助(盡管問題仍然存在——為什么會這樣,以及我們將如何處理)!

當然,我們可以手動排除任何場景。

就像我的情況一樣,我完全需要isFinite()的輸出,除了 null 情況、空字符串情況和純空格字符串情​​況。 此外,我對非常龐大的數字也不感到頭疼。 所以我的代碼看起來像這樣:

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

而且,這是我生成表格的 JavaScript:

/**
 * 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(`  `, `&nbsp;&nbsp;`);

// Print markdown to console
console.log(markdownOutput);

有人也可能從基於正則表達式的答案中受益。 這里是:

一個襯墊是整數:

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

一班是數字:接受整數和小數

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

為什么jQuery的實現不夠好?

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

Michael 提出了這樣的建議(盡管我在這里偷了“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));
};

除了手動測試我將在當前困境中遇到的少數用例之外,我還沒有通過其他方式對這些中的任何一個進行過很多測試,這些都是非常標准的東西。 這是一種“站在巨人的肩膀上”的局面。

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

它對 TypeScript 無效,因為:

declare function isNaN(number: number): boolean;

對於 TypeScript,您可以使用:

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

我喜歡這種簡單。

Number.isNaN(Number(value))

以上是常規的 Javascript,但我將它與typescript typeguard結合使用以進行智能類型檢查。 這對於打字稿編譯器為您提供正確的智能感知非常有用,並且沒有類型錯誤。

打字稿類型保護

警告:請參閱下面 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;
}

假設您有一個屬性widthnumber | 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;    
}

typeguard 足夠聰明,可以將if語句中的width類型限制為 ONLY string 這允許編譯器允許width.endsWith(...)如果類型是string | number則不允許。 string | number

你可以調用 typeguard 任何你想要的isNotNumberisNumberisStringisNotString但我認為isString有點模棱兩可且難以閱讀。

防范空字符串和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 (區分大小寫)不同,作為測試用例以字符串格式傳遞給上述任何方法的NumberMath對象中的常量將被確定為不是數字。
  • 有關如何將參數轉換為Number以及為什么存在null字符串和空字符串的邊緣情況的說明,請參見此處

引用:

isNaN(num) // 如果變量不包含有效數字,則返回 true

如果您需要檢查前導/尾隨空格,則不完全正確 - 例如,當需要一定數量的數字時,您可能需要獲取 '1111' 而不是 '111' 或 '111' 作為 PIN輸入。

更好地使用:

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

parseInt(),但請注意,這個函數有點不同,例如它為 parseInt("100px") 返回 100。

這是建立在以前的一些答案和評論的基礎上的。 以下內容涵蓋了所有邊緣情況,也相當簡潔:

const isNumRegEx = /^-?(\d*\.)?\d+$/;

function isNumeric(n, allowScientificNotation = false) {
    return allowScientificNotation ? 
                !Number.isNaN(parseFloat(n)) && Number.isFinite(n) :
                isNumRegEx.test(n);
}

好吧,我正在使用我制作的這個......

到目前為止它一直在工作:

function checkNumber(value) {
    return value % 1 == 0;
}

如果您發現它有任何問題,請告訴我。

如果有人能做到這一點,我會花一些時間來嘗試修補 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

歡迎任何建議。 :]

我最近寫了一篇關於如何確保變量是有效數字的文章: https ://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.md 文章解釋了如何確保浮點或整數,如果是的話重要( +x~~x )。

本文假設變量是一個string或一個number開頭,並且trim可用/polyfill。 擴展它以處理其他類型也不難。 這是它的肉:

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

檢查JS中的數字:

  1. 檢查它是否是數字的最佳方法:

     isFinite(20) //True
  2. 從字符串中讀取一個值。 CSS *:

     parseInt('2.5rem') //2 parseFloat('2.5rem') //2.5
  3. 對於整數:

     isInteger(23 / 0) //False
  4. 如果值為 NaN:

     isNaN(20) //False

PFB 工作解決方案:

 function(check){ 
    check = check + "";
    var isNumber =   check.trim().length>0? !isNaN(check):false;
    return isNumber;
    }

免去尋找“內置”解決方案的麻煩。

沒有一個好的答案,而且這個帖子中被高度評價的答案是錯誤的。

npm install is-number

在 JavaScript 中,可靠地檢查一個值是否為數字並不總是那么簡單。 開發人員通常使用 +、- 或 Number() 將字符串值轉換為數字(例如,當從用戶輸入、正則表達式匹配、解析器等返回值時)。 但是有許多非直觀的邊緣情況會產生意想不到的結果:

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

這似乎抓住了看似無限數量的邊緣情況:

function isNumber(x, noStr) {
    /*

        - Returns true if x is either a finite number type or a string containing only a number
        - If empty string supplied, fall back to explicit false
        - Pass true for noStr to return false when typeof x is "string", off by default

        isNumber(); // false
        isNumber([]); // false
        isNumber([1]); // false
        isNumber([1,2]); // false
        isNumber(''); // false
        isNumber(null); // false
        isNumber({}); // false
        isNumber(true); // false
        isNumber('true'); // false
        isNumber('false'); // false
        isNumber('123asdf'); // false
        isNumber('123.asdf'); // false
        isNumber(undefined); // false
        isNumber(Number.POSITIVE_INFINITY); // false
        isNumber(Number.NEGATIVE_INFINITY); // false
        isNumber('Infinity'); // false
        isNumber('-Infinity'); // false
        isNumber(Number.NaN); // false
        isNumber(new Date('December 17, 1995 03:24:00')); // false
        isNumber(0); // true
        isNumber('0'); // true
        isNumber(123); // true
        isNumber(123.456); // true
        isNumber(-123.456); // true
        isNumber(-.123456); // true
        isNumber('123'); // true
        isNumber('123.456'); // true
        isNumber('.123'); // true
        isNumber(.123); // true
        isNumber(Number.MAX_SAFE_INTEGER); // true
        isNumber(Number.MAX_VALUE); // true
        isNumber(Number.MIN_VALUE); // true
        isNumber(new Number(123)); // true
    */

    return (
        (typeof x === 'number' || x instanceof Number || (!noStr && x && typeof x === 'string' && !isNaN(x))) &&
        isFinite(x)
    ) || false;
};

因此,這將取決於您希望它處理的測試用例。

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

截至今天,所有其他答案似乎都未能通過其中一個測試用例。

這種方式對我有用。

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
)

這是一個優雅的單行代碼來檢查sNum是否是一個有效的數值。 該代碼還針對各種輸入進行了測試。

// returns True if sNum is a numeric value    
!!sNum && !isNaN(+sNum.replace(/\s|\$/g, ''));  

@gman 致敬以發現錯誤。

我用這個函數作為表單驗證工具,不想讓用戶寫指數函數,所以想出了這個函數:

<script>

    function isNumber(value, acceptScientificNotation) {

        if(true !== acceptScientificNotation){
            return /^-{0,1}\d+(\.\d+)?$/.test(value);
        }

        if (true === Array.isArray(value)) {
            return false;
        }
        return !isNaN(parseInt(value, 10));
    }


    console.log(isNumber(""));              // false
    console.log(isNumber(false));           // false
    console.log(isNumber(true));            // false
    console.log(isNumber("0"));             // true
    console.log(isNumber("0.1"));           // true
    console.log(isNumber("12"));            // true
    console.log(isNumber("-12"));           // true
    console.log(isNumber(-45));             // true
    console.log(isNumber({jo: "pi"}));      // false
    console.log(isNumber([]));              // false
    console.log(isNumber([78, 79]));        // false
    console.log(isNumber(NaN));             // false
    console.log(isNumber(Infinity));        // false
    console.log(isNumber(undefined));       // false
    console.log(isNumber("0,1"));           // false



    console.log(isNumber("1e-1"));          // false
    console.log(isNumber("1e-1", true));    // true
</script>

Number.isInteger()可用於檢查某個值是否為數字:

Number.isInteger(0);         // true
Number.isInteger(1);         // true
Number.isInteger(-100000);   // true
Number.isInteger(99999999999999999999999); // true

Number.isInteger(0.1);       // false
Number.isInteger(Math.PI);   // false

Number.isInteger(NaN);       // false
Number.isInteger(Infinity);  // false
Number.isInteger(-Infinity); // false
Number.isInteger('10');      // false
Number.isInteger(true);      // false
Number.isInteger(false);     // false
Number.isInteger([1]);       // false

Number.isInteger(5.0);       // true
Number.isInteger(5.000000000000001); // false
Number.isInteger(5.0000000000000001); // true

取自這里

如果您喜歡棘手的方法並且喜歡讓您的同事感到困惑,您可以使用:

const isNumeric = str => parseFloat(str) === parseFloat(str)

證明:

 const isNumeric = str => parseFloat(str) === parseFloat(str) console.log(isNumeric('10')) console.log(isNumeric('-10.2')) console.log(isNumeric('15abc')) console.log(isNumeric('0.0001')) console.log(isNumeric('abc')) console.log(isNumeric('abc123'))

我認為 isFinite() 最適合所有人。

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

在我的應用程序中,我們只允許 az AZ 和 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)] 中的一個長期存在的錯誤,我不能這么說,但這正是我們所需要的。

我的解決方案:

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

您可以在循環內添加其他條件,以滿足您的特定需求。

我的嘗試有點令人困惑,也許不是最好的解決方案

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));           // false
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

您可以使用類型(例如流庫)來獲得靜態的編譯時檢查。 當然對於用戶輸入不是非常有用。

// @flow

function acceptsNumber(value: number) {
  // ...
}

acceptsNumber(42);       // Works!
acceptsNumber(3.14);     // Works!
acceptsNumber(NaN);      // Works!
acceptsNumber(Infinity); // Works!
acceptsNumber("foo");    // Error!

這是 isNumber 實現的高性能(2.5*10^7 迭代/s @3.8GHz Haswell)版本。 它適用於我能找到的每個測試用例(包括符號):

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

測試字符串或數字是否為數字

const isNumeric = stringOrNumber =>
  stringOrNumber == 0 || !!+stringOrNumber;

或者,如果您想將字符串或數字轉換為數字

const toNumber = stringOrNumber =>
  stringOrNumber == 0 || +stringOrNumber ? +stringOrNumber : NaN;

我在 Angular 中使用了這個功能

 isNumeric(value: string): boolean {
             let valueToNumber = Number(value);
             var result = typeof valueToNumber == 'number' ;
             if(valueToNumber.toString() == 'NaN')
             {
                result = false;
             }
             return result;
          }

這家伙怎么樣

const a = '1'

const isNumber = Number(a) === +a

這是檢查變量是否不是數字的一種可能方法:

(isNaN(foo) || ((foo !== 0) && (!foo)))

這意味着foo要么是假的,但不同於 0,要么isNaN(foo)是真的。

執行此類檢查的另一種方法是

!isNaN(parseFloat(foo))

typeof運算符返回一個字符串,指示操作數值的類型。

對於數字,它返回“數字”字符串。

function isNumber(num) {
   return typeof num === "number";
}

您也可以使用簡單的 parseInt function ......例如使用 if 條件

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

只需使用isNaN() ,這會將字符串轉換為數字,如果獲得有效數字,將返回false ...

isNaN("Alireza"); //return true
isNaN("123"); //return false

我正在使用以下內容:

const isNumber = s => !isNaN(+s)

如果您正在尋找一個正數(例如門牌號),只需使用:

if (mystring > 0) ...

我這樣做:

function isString(value)
{
    return value.length !== undefined;
}
function isNumber(value)
{
    return value.NaN !== undefined;
}

當然,如果您傳遞一些其他定義了“長度”的對象,isString() 將在這里被絆倒。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM