文字列が正の整数であることを検証する


200

JavaScriptの文字列が正の整数であることを確認する最も簡単なフェイルセーフテストが必要です。

isNaN(str)すべての種類の非整数値に対してtrueを返しparseInt(str)、「2.5」などの浮動小数点文字列に対して整数を返します。また、jQueryプラグインを使用する必要もありません。


7
「+2」を許可しますか?「0.1e1」はどうですか?「1.0000」はどうですか?
Phrogz、2012年

このisNaN()概念Not a Numberは、IEEE 794浮動小数点仕様で非常に具体的な意味を持っているため、関数の動作は同じです。「この値は数値ではないのですか?」という単純な口語的な質問への回答を提供するつもりはありません。
先のとがった

3
質問は極端にあいまいです。そのようなものは存在しないため、「文字列が整数である」ことを検証することはできません。オブジェクトが文字列と数値になることはできません。おそらく「文字列が整数の有効な表現であるかどうかをテストする方法」を意味していましたが、これに答えるには、あなたが話している言語または「文化」を知る必要があります。たとえば、٢‎٣٤またはMCMXIXどちらも有効な整数表現ですが、これらを解析できるコードを探しているとは思いません。人々が混乱しているように見えるので、サポートする数値形式を指定してください。
georg、

5
「極端に曖昧」はそれ自体少し極端だと思います。とにかく...コンテキストは、英語圏の国で使用されているショッピングカートの数量入力フィールドの検証なので、数字のみです。「ポジティブ」とは、ゼロより大きいことを意味しました。次を受け入れますか: "+2"はい、 "0.1e1"いいえ、 "1.000"確かにそうではありません。ただし、これらのさまざまな特殊なシナリオを含める/除外するように調整できる回答を提供できる場合は、追加のアップを提供することを約束します(他の人もそうするはずです)。
ミックバーン

回答:


296

あなたのための2つの答え:

  • 解析に基づく

  • 正規表現

どちらの場合でも、「正の整数」にはが含まれる0と解釈していることに注意してください。0が、正ではありません。禁止したい場合は、メモを含めます0

解析に基づく

妥当な値の範囲で正規化された10進整数文字列にする場合は、次のようにします。

function isNormalInteger(str) {
    var n = Math.floor(Number(str));
    return n !== Infinity && String(n) === str && n >= 0;
}

または、空白と先行ゼロを許可する場合:

function isNormalInteger(str) {
    str = str.trim();
    if (!str) {
        return false;
    }
    str = str.replace(/^0+/, "") || "0";
    var n = Math.floor(Number(str));
    return n !== Infinity && String(n) === str && n >= 0;
}

ライブテストベッド(先行ゼロまたは空白を処理しない):

(ライブテストベッドでの先行ゼロと空白のためのハンドリング):

許可しない場合は0、に変更>= 0してください> 0。(または、先行ゼロを許可するバージョンでは|| "0"replace行のを削除します。)

仕組み:

  1. 空白と先行ゼロを許可するバージョンでは:

    • str = str.trim(); 先頭と末尾のホワイトスペースを削除します。
    • if (!str) 空の文字列をキャッチして戻ります。残りの作業を行う意味はありません。
    • str = str.replace(/^0+/, "") || "0"; 文字列からすべての先行0を削除します—ただし、その結果として空白の文字列になる場合は、単一の0を復元します。
  2. Number(str)str数値に変換します。数値は小数部分を含む場合もあれば、の場合もありますNaN

  3. Math.floor:数値を切り捨てます(小数部分を切り捨てます)。

  4. String(...):結果を通常の10進数文字列に変換します。本当に大きな数の場合、これは科学的表記になり、このアプローチを破る可能性があります。(分割の場所がよくわかりません。詳細は仕様に記載されていますが、整数の場合、21桁を超えた時点であると考えています[IEEE-754のように、その時点で数値は非常に不正確になっています。倍精度の数値は、およそ15桁の精度しかありません。)

  5. ... === str:元の文字列と比較します。

  6. n >= 0:ポジティブであることを確認します。

これは、入力"+1"、そのString(...)段階で同じ科学表記に戻らない科学表記の入力、およびJavaScriptが使用する数値の種類(IEEE-754倍精度バイナリ浮動小数点)の場合は失敗します。指定された値(9,007,199,254,740,992を超える多くの整数を含む)とは異なる値に近い解析を正確に表すことはできません。たとえば、1234567890123456789失敗)。前者は簡単な修正ですが、後者の2つはそれほど多くはありません。

正規表現

もう1つのアプローチは、正規表現を介して文字列の文字をテストすることです。目的がオプション(たとえば)の+0に通常の10進形式の文字列または文字列を許可するだけの場合です。

function isNormalInteger(str) {
    return /^\+?(0|[1-9]\d*)$/.test(str);
}

ライブテストベッド:

仕組み:

  1. ^:文字列の先頭に一致

  2. \+?:単一のオプションを許可します+(不要な場合は削除してください)

  3. (?:...|...):次の2つのオプションのいずれかを許可します(キャプチャグループを作成せずに):

    1. (0|...)0独自に許可...

    2. (...|[1-9]\d*):...またはそれ以外の数字で始まり0、その後に任意の数の10進数が続く数字。

  4. $:文字列の終わりに一致します。

許可しない場合0(正ではないため)、正規表現はそのままになります/^\+?[1-9]\d*$/(たとえば、許可する必要があった代替を失う可能性があります)0)。

先行ゼロ(0123、00524)を許可する場合は、代替(?:0|[1-9]\d*)を次のものに置き換えます。\d+

function isNormalInteger(str) {
    return /^\+?\d+$/.test(str);
}

空白を許可する場合は、\s*直後^\s*直前に追加します$ます。

これを数値に変換するときの注意:最近のエンジンではおそらく使用+strまたはNumber(str)実行しても問題ありませんが、古いエンジンでは非標準の(以前は許可されていた)方法で拡張され、先行ゼロは8進数を意味します(基数8)、たとえば "010" => 8.数値を検証したら、安全に使用parseInt(str, 10)して、10進数(基数10)として解析されることを確認できます。parseInt文字列の最後にあるゴミは無視しますが、正規表現には何もないことを確認しました。


両方Number(' ')ともNumber('')戻りますが0NaN代わりに戻ります。
neurino 2013年

@TJCrowderは大丈夫ですが、どういうわけか拒否される '' 2a ''のような文字列が必要です、をparseInt返します2
neurino 2013年

@neurino:/\D/.test('2a')真です(非数字があるため)。だから多分if (!/\D/.test(str) && !isNan((num = parseInt(str, 10))) { /* Valid number in num */}...頭の真上から...
TJクラウダー

パフォーマンスに関しては、どちらの方法が速いでしょうか?またはどちらがお勧めですか?
phkavitha 2013

@phkavitha:JavaScriptのパフォーマンスに関する質問への答えは、ほとんどの場合、「エンジンによって異なる」ため、「それは場合によります」です。jsperf.comを使用して、ターゲットエンジン/ブラウザをテストできます。この操作が特定のアプリのボトルネックになる可能性は低いと思います... :-)
TJ Crowder 2013

76

解決策1

JavaScript整数を最大値(つまり)と見なす場合、次の短い解決策が完全に機能します。4294967295Math.pow(2,32)-1

function isPositiveInteger(n) {
    return n >>> 0 === parseFloat(n);
}

説明:

  1. ゼロフィル右シフト演算子は、3つの重要なことを行います。
    • 小数部を切り捨てます
      • 123.45 >>> 0 === 123
    • 負の数のシフトを行います
      • -1 >>> 0 === 4294967295
    • の範囲で「動作する」 MAX_INT
      • 1e10 >>> 0 === 1410065408
      • 1e7 >>> 0 === 10000000
  2. parseFloat文字列番号の解析を修正します(NaN非数値文字列の設定)

テスト:

"0"                     : true
"23"                    : true
"-10"                   : false
"10.30"                 : false
"-40.1"                 : false
"string"                : false
"1234567890"            : true
"129000098131766699.1"  : false
"-1e7"                  : false
"1e7"                   : true
"1e10"                  : false
"1edf"                  : false
" "                     : false
""                      : false

デモ: http : //jsfiddle.net/5UCy4/37/


解決策2

別の方法はNumber.MAX_VALUE、まで、つまり約まで有効なすべての数値に適しています1.7976931348623157e+308

function isPositiveInteger(n) {
    return 0 === n % (!isNaN(parseFloat(n)) && 0 <= ~~n);
}

説明:

  1. !isNaN(parseFloat(n))フィルタするために使用された純粋な文字列値を、例えば""" ""string";
  2. 0 <= ~~nフィルタネガティブと大きな非整数値、例えば"-40.1""129000098131766699";
  3. (!isNaN(parseFloat(n)) && 0 <= ~~n)true値が数値正の場合に返されます。
  4. 0 === n % (...)値が非フロートであるかどうかを確認する-ここでは、(...)(3を参照)として評価され0た場合にfalse、およびAS 1の場合true

テスト:

"0"                     : true
"23"                    : true
"-10"                   : false
"10.30"                 : false
"-40.1"                 : false
"string"                : false
"1234567890"            : true
"129000098131766699.1"  : false
"-1e10"                 : false
"1e10"                  : true
"1edf"                  : false
" "                     : false
""                      : false

デモ: http : //jsfiddle.net/5UCy4/14/


以前のバージョン:

function isPositiveInteger(n) {
    return n == "0" || ((n | 0) > 0 && n % 1 == 0);
}

デモ: http : //jsfiddle.net/5UCy4/2/


-空の文字列または1290000981231123.1など多数お試しくださいjsfiddle.net/5UCy4/1
ニコ

@gdoronと同じ~~val、小数部分を切り捨てます。2つではなく1つのビット単位の演算を行うため、少し高速です。
VisioN 2012年

すばらしい答えです。個人的には、読みやすさのためにもう少し冗長にすることを(!isNaN(parseFloat(n)) && n % 1 === 0 && 0 <= ~~n)
好みます

true, false, 0xFF、および他の値isPositiveIntegerは検出されずに通過します。
Xeoncross

1
これは埋め込みゼロも処理します(良い!)。これをテストに追加できます。
Rashack

21

正規表現が行く方法のように見えます:

var isInt = /^\+?\d+$/.test('the string');

「1.0」または「.1e1」が許可されていない限り、閉じます。
Phrogz、2012年

1290000192379182379123782900192981231は整数ですが、JavaScriptネイティブ番号では正確に表現できないため、正規表現を使用して数値変換を行い、機能することを確認する必要があります。
2012年

これは非常に不正確なソリューションです。
usr

@usr:0通常は予期しないところにリードできると思いますが、大部分は問題ないようです。
TJクラウダー、2012年

範囲が最大で2 ^ 31-1であることを確認せず、アラビア数字を許可しません。これはハックであり、良い解決策ではありません。最善の解決策は、この質問で最も賛成票を獲得することです。それを使ってみませんか?それはあらゆる点で優れています。
usr

17

ノードで動作し、すべてのブラウザー(IEとOpera Miniを除く)の90%以上で機能する最新のソリューションは、Number.isIntegerを使用し、その後単純なポジティブチェックを実行することです。

Number.isInteger(x) && x > 0

これはECMAScript 2015で確定されました

function isPositiveInteger(x) {
    return Number.isInteger(x) && x > 0
}

ポリフィルは:

Number.isInteger = Number.isInteger || function(value) {
  return typeof value === 'number' && 
    isFinite(value) && 
    Math.floor(value) === value;
};

文字列または数値の形式の入力をサポートする必要がある場合は、既存のすべての回答(2018年2月1日)が何らかの入力形式で失敗した後、この関数を使用して大規模なテストスイートを作成できます。

function isPositiveInteger(v) {
  var i;
  return v && (i = parseInt(v)) && i > 0 && (i === v || ''+i === v);
}

4

これは、これとほぼ同じ質問です:

JavaScriptで10進数を検証する-IsNumeric()

それの答えは:

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

したがって、正の整数は次のようになります。

function isPositiveInteger(n) {
  var floatN = parseFloat(n);
  return !isNaN(floatN) && isFinite(n) && floatN > 0
      && floatN % 1 == 0;
}

「JavaScriptでの数値の検証」の質問とほぼ同じであることはわかっていますが、全体を読み通しましたが、整数の文字列表現についての質問は、それ自体のページに値するはずです。
ミックバーン

2
return ((parseInt(str, 10).toString() == str) && str.indexOf('-') === -1);

「0001」のような文字列を指定しても機能しません


2

私の関数は、numberが+ veであり、10進数値である可能性があるかどうかをチェックします。

       function validateNumeric(numValue){
            var value = parseFloat(numValue);
            if (!numValue.toString().match(/^[-]?\d*\.?\d*$/)) 
                    return false;
            else if (numValue < 0) {
                return false;
            }
            return true;        
        }

2

上記のVisioNの答えに基づいて構築するために、jQuery検証プラグインを使用している場合、これを使用できます。

$(document).ready(function() {
    $.validator.addMethod('integer', function(value, element, param) {
        return (value >>> 0 === parseFloat(value) && value > 0);
    }, 'Please enter a non zero integer value!');
}

次に、通常のルールセットで使用するか、次のように動的に追加します。

$("#positiveIntegerField").rules("add", {required:true, integer:true});

2

シンプルな

function isInteger(num) {
  return (num ^ 0) === num;
}

console.log(isInteger(1));

Numberを拡張して、プロトタイプを介して関数を割り当てることもできます。


1

HTML5フォームを使用している場合はmin="0"、form要素の属性を使用できます<input type="number" />。これはすべての主要なブラウザでサポートされています。このような単純なタスクにはJavascriptは含まれていませんが、新しいHTML標準に統合されています。https://www.w3schools.com/tags/att_input_min.aspに記載されています


0

(~~a == a)どこa文字列です。


1
負の数の場合、これは失敗します:~~"-1" == "-1"が返されtrueます。そしてOPは正の整数だけを求めました。
Igor Milla

1
''と ''でも失敗します。
neverfox

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.