web-dev-qa-db-ja.com

文字列が有効な数字かどうかをチェックするためのJavaScriptの(組み入れの)方法

私は、古いVB6のIsNumeric()関数と同じ概念的な空間に何かあることを願っていますか?

937
Electrons_Ahoy

変数(文字列を含む)が数値かどうかを調べるには、それが数値ではないかどうかを確認します。

これは、変数の内容が文字列か数値かに関係なく機能します。

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

数値を含む文字列を数値に変換するには

文字列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 two may be different
parseInt('12a5')   // 12       from what you expected to see. 

フロート

+numとは異なり、parseIntは(名前が示すように)小数点以下のすべてを切り捨ててfloatを整数に変換することに注意してください(parseInt()のためを使用したい場合は、 代わりに別の方法を使うほうがおそらくいいでしょう ):

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

空の文字列

空の文字列は少し直感に反するかもしれません。 +numは空の文字列をゼロに変換し、isNaN()は同じことを仮定します。

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

しかしparseInt()は同意しません:

parseInt('')       // NaN
1915
Dan

そして、あなたは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
}
43
roenving

文字列に数字、任意の数字(整数または浮動小数点)、および正確な数字のみが含まれるようにしたい場合は、cannotparseInt()/parseFloat()Number()、または!isNaN()を単独で使用します。 !isNaN()は、実際にNumber()が数値を返すときにtrueを返し、falseNaNを返す場合に返されるので、残りの説明から除外することに注意してください。

parseFloat()の問題は、文字列にonlyおよびexactly数字が含まれていなくても、文字列に数字が含まれている場合に数字が返されることです。

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()が返すべきでない場合に数字を返すすべてのケースで正しいことを行い、逆の場合も同様です。したがって、文字列が実際に正確で数字だけであるかどうかを調べるには、両方の関数を呼び出してbothが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))
}
35
Michael

文字列が整数であるか(小数点以下の桁数がない)チェックしようとしているのであれば、正規表現を使用するのが良いでしょう。 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
30
Gavin

isNan関数を試してください

IsNaN()関数は、値が不正な数値(Not-a-Number)かどうかを判断します。

値がNaNと等しい場合、この関数はtrueを返します。そうでなければfalseを返します。

この関数はNumber特有の Number.isNaN() メソッドとは異なります。

グローバルなisNaN()関数は、テストされた値をNumberに変換してからテストします。

Number.isNan()は値をNumberに変換しません。また、Number型ではない値についてはtrueを返しません。

20
theraccoonbear

昔の質問ですが、与えられた答えには欠けている点がいくつかあります。

科学表記法

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

しかし、これでも完成には程遠いです。先行ゼロはここでは処理されませんが、長さテストには問題があります。

10
mark

たぶんこの質問に遭遇する人が一人か二人いるでしょう。彼らはいつもより私がしたように もっと厳密な チェックを必要とします。その場合、これは役に立ちます。

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

注意してください。これは.140.00008000.1のような文字列を拒否します。これは非常にうるさい - 文字列は " 最小の完璧な形式 "がこのテストに合格するのに一致しなければならない。

それはStringNumberコンストラクタを使用して文字列を数値にキャストし、またその逆に変換して、JavaScriptエンジンの "完全最小形式"(最初のNumberコンストラクタで変換されたもの)が元の文字列と一致するかどうかをチェックします。

6
user993683

この質問に対する一般的な回答には、かなりの数の欠陥があります(他のユーザー2人が強調しています)。これは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
6
Hamzeen Hameem

私はテストしましたが、Michaelの解決策が最善です。上記の彼の答えに投票してください(それを見つけるには、「この文字列を本当に確認したい場合はこのページを検索してください)。本質的に、彼の答えはこれです:

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

それは私がここで文書化したすべてのテストケースでうまくいきます: https://jsfiddle.net/wggehvp9/5/

他の解決策の多くは、これらのEdgeのケースでは失敗します: ''、null、 ""、true、[]。理論的には、適切なエラー処理を使用してそれらを使用できます。例えば、

return !isNaN(num);

または

return (+num === +num);

/\s /、null、 ""、true、false、[]などの特殊な処理を行います。

5
JohnP2

parseInt()、ただしこの関数はparseInt( "100px")に対して100を返すという意味では少し異なります。

5
liggett78

コンストラクタに引数を渡すときに Number の結果を使用できます。

引数(文字列)を数値に変換できない場合は、NaNが返されるため、指定した文字列が有効な数値かどうかを判断できます。

注意:空の文字列、またはNumberとして'\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
5
GibboK

さて、私は私が作ったこれを使っています...

それはこれまで働いています:

function checkNumber(value) {
    if ( value % 1 == 0 )
    return true;
    else
    return false;
}

何か問題があれば教えてください。

4
Rafael

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

ただし、後者のバージョンには2つの新しい変数があります。次のようにすれば、そのうちの1つを回避できます。

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

私はこれらのどれもあまりテストしていません。私が現在経験しているいくつかのユースケースを手動でテストする以外の方法でテストしたことはありません。これが「巨人の立場」です。

見積もり:

isNaN(num)//変数に有効な数値が含まれていない場合はtrueを返します

先頭または末尾のスペースをチェックする必要がある場合、たとえば、ある程度の桁数が必要で、_の場合は '111'や '111'ではなく '1111'を取得する必要がある場合など、完全には当てはまりません。PIN入力。

より良い使い方:

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

だれかがこれまでのところ遠くまで落ち込んだ場合、私は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

どんな提案でも歓迎します。 :]

2
The Dembinski
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 ...
}
2
gvlax

私はこれの単純さが好きです。

Number.isNaN(Number(value))

上記は通常のJavascriptですが、私はこれをTypeScript typeguard と組み合わせてスマートな型チェックに使用しています。これはTypeScriptコンパイラにとって正しいインテリセンスを与え、型エラーを起こさないのに非常に便利です。

TypeScriptタイプガード

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

number | stringというプロパティwidthがあるとしましょう。あなたはそれが文字列かどうかに基づいてロジックをしたいかもしれません。

var width: number|string;
width = "100vw";

if (isNotNumber(width)) 
{
    // the compiler knows that width here must be a string
    if (width.endsWith('vw')) 
    {
        // we have a 'width' such as 100vw
    } 
}
else 
{
    // the compiler is smart and knows width here must be number
    var doubleWidth = width * 2;    
}

Typeguardはwidthステートメント内のifの型をstringのみに制限するのに十分スマートです。これにより、コンパイラはwidth.endsWith(...)を許可することができますが、型がstring | numberの場合は許可されません。

isNotNumberisNumberisStringisNotStringのどのようなタイプガードでも呼び出すことができますが、isStringは曖昧で読みづらいと思います。

1
Simon_Weaver

多少混乱している私の試みは、おそらく最良の解決策ではない

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

PFBのワーキングソリューション:

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

「組み込み」の解決策を見つけようとする際の頭痛の種を自分で省いてください。

良い答えはありません、そしてこのスレッドで非常に支持された答えは間違っています。

npm install is-number

JavaScriptでは、値が数値であるかどうかを確実にチェックするのと同じくらい簡単ではありません。開発者が+、 - 、またはNumber()を使用して文字列値を数値にキャストするのは一般的です(たとえば、値がユーザー入力、正規表現の一致、パーサーなどから返される場合)。しかし、予期しない結果をもたらす直感的ではないEdgeのケースが多数あります。

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

IsNumber実装の高性能(2.5 * 10 ^ 7反復/秒@ 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;
  };
})();
0
c7x43t

flow librar yのように型を利用して、静的なコンパイル時のチェックを行うことができます。もちろんユーザ入力にはそれほど有用ではありません。

// @flow

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

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

私のアプリケーションでは、私たちは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)]、それについて話すことはできませんが、まさに必要なものです。 。

0
rwheadon

私は最近、変数が有効な数値であることを確認する方法についての記事を書きました: https://github.com/jehugaleahsa/artifacts/blob/master/1818/TypeScript_num_hack.md それが重要な場合は、ポイントまたは整数(+x~~x)。

この記事では、変数は最初からstringまたはnumberであり、trimはavailable/polyfilledであると仮定しています。他の型を扱うためにそれを拡張することも難しくありません。これがその要点です。

// 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
}
0
Travis Parks

isNaN()を使うだけで、これは文字列を number に変換し、有効な number を得ればfalse...を返します。

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

私は以下を使っています:

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

TypeScriptでは無効です。

declare function isNaN(number: number): boolean;

TypeScriptの場合は、次のものを使用できます。

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

0
Greg Woz

これはsNumが有効な数値かどうかを調べるためのワンライナーです。さまざまな入力についてテスト済みです。

!isNaN(+s.replace(/\s|\$/g, ''));  // returns True if numeric value
0
lifebalance

普通のJavaScriptを使う:

Number.isNaN(Number('1')); // false
Number.isNaN(Number('asdf')); // true

Lodashを使う:

_.isNaN(_.toNumber('1')); // false
_.isNaN(_.toNumber('asdf')); // true
0
Abtin Gramian

私の解決策:

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

特定のニーズに合わせて、ループ内に条件を追加することができます。

0
GoTo