자바 스크립트에서 10 진수의 유효성을 검사합니다 - isnumeric ()
질문
자바 스크립트에서 10 진수를 검증하는 가장 깨끗하고 가장 효과적인 방법은 무엇입니까?
보너스 포인트 :
- Clarity. Solution should be clean and simple.
- Cross-platform.
테스트 케이스 :
01. IsNumeric('-1') => true
02. IsNumeric('-1.5') => true
03. IsNumeric('0') => true
04. IsNumeric('0.42') => true
05. IsNumeric('.42') => true
06. IsNumeric('99,999') => false
07. IsNumeric('0x89f') => false
08. IsNumeric('#abcdef') => false
09. IsNumeric('1.2.3') => false
10. IsNumeric('') => false
11. IsNumeric('blah') => false
답변
@ Joel의 답변은 꽤 가깝지만 다음과 같은 경우 실패합니다.
// Whitespace strings:
IsNumeric(' ') == true;
IsNumeric('\t\t') == true;
IsNumeric('\n\r') == true;
// Number literals:
IsNumeric(-1) == false;
IsNumeric(0) == false;
IsNumeric(1.1) == false;
IsNumeric(8e5) == false;
얼마 전 나는 isNumeric 함수를 구현해야하였고, 변수가 숫자 값이 포함되어 있는지, 유형에 관계없이 숫자 값을 포함하는 문자열 일 수있는 문자열 일 수있는 문자열이 될 수 있습니다 (지수 표기법을 고려해야했습니다.숫자 개체, 거의 모든 것이 해당 함수에 전달 될 수 있으며 유형 강압을 돌보는 일들의 가정을 만들 수 없었습니다 (예 : + true == 1; 그러나 참된 "숫자로 간주되어서는 안됩니다").
나는이 +30 단위 테스트 세트를 수많은 함수 구현으로 공유 할 가치가 있으며 모든 테스트를 통과하는 것을 공유 할 가치가 있다고 생각합니다.
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
추신IsNan & IsFinite는 강제로의 숫자로 변환으로 인해 혼란스러운 행동을합니다.ES6에서 Numbersnan & Numbers.isfinite는 이러한 문제를 해결할 것입니다.그들을 사용할 때 그것을 염두에 두십시오.
업데이트 : jQuery가 지금은 jQuery를 수행하는 방법 (2.2 안정) :
isNumeric: function(obj) {
var realStringObj = obj && obj.toString();
return !jQuery.isArray(obj) && (realStringObj - parseFloat(realStringObj) + 1) >= 0;
}
업데이트 : Angular 4.3 :
export function isNumeric(value: any): boolean {
return !isNaN(value - parseFloat(value));
}
답변
arrrgh!정규 표현식 답변을 듣지 마십시오.regex는 이것을 위해 icky이며, 나는 그냥 성능을 말하고 있지 않습니다.당신의 정규 표현식으로 실수를 벗을 수없고, 미묘하게 쉽게 만들 수 있습니다.
IsNan ()을 사용할 수없는 경우 이것은 훨씬 더 잘 작동해야합니다.
function IsNumeric(input)
{
return (input - 0) == input && (''+input).trim().length > 0;
}
어떻게 작동하는지 여기에 있습니다.
(입력 -0) 표현식은 입력 값에 대한 JavaScript를 입력 강압을 수행합니다.먼저 뺄셈 작업의 숫자로 해석해야합니다.숫자로 변환이 실패하면 표현식이 NaN이됩니다.이 숫자 결과는 다음과 같이 전달한 원래 값과 비교됩니다. 왼쪽이 숫자이기 때문에 유형 강제가 다시 사용됩니다.이제 양쪽의 입력이 동일한 원래 값과 동일한 유형으로 강제로 강제적 이었으므로 항상 동일해야한다고 생각합니다 (항상 사실).그러나 NAN이 NAN과 동일하지 않으므로 숫자로 변환 할 수없는 값 (및 숫자로 변환 할 수없는 값만)이 표시되는 특별한 규칙이 있습니다.
길이에 대한 수표는 빈 문자열을 포함하는 특별한 경우입니다.또한 0x89F 테스트에 속하는 것이지만, 숫자 리터럴을 정의하는 괜찮은 방법은 많은 환경에서는 그렇습니다.특정 시나리오를 잡으려고하면 추가 확인을 추가 할 수 있습니다.그게 isnan ()을 사용하지 않는 이유가 있으면 추가 검사를 수행 할 수있는 isnan () 주위에 자신의 함수를 감싼다.
요약하면 값을 숫자로 변환 할 수 있는지 여부를 알고 싶다면 실제로 숫자로 변환하려고합니다.
나는 다시 갔고, 공백 문자열이 예상되는 출력을 가지고 있지 않은 이유에 대한 몇 가지 연구를했고, 나는 지금 그것을 얻는 것 같아요. 빈 문자열은 NaN보다는 0으로 강제로 강요됩니다.길이 검사 가이 사례를 처리하기 전에 문자열을 다듬을 수 있습니다.
새 코드에 대한 장치 테스트를 실행하고 무한대 및 부울 리터럴에서만 실패하고 문제가되는 유일한 시간은 코드를 생성하는 경우 (실제로 누가 리터럴을 입력하고 숫자가 있는지 확인하십시오.당신은 알아야합니다) 그리고 그것은 생성 할 수있는 이상한 코드가 될 것입니다.
그러나 이제까지 사용하는 유일한 이유는 당신이 isnan ()을 피해야하는 어떤 이유로
답변
이런 식으로 잘 작동하는 것 같습니다.
function IsNumeric(input){
var RE = /^-{0,1}\d*\.{0,1}\d+$/;
return (RE.test(input));
}
한 줄로 :
const IsNumeric = (num) => /^-{0,1}\d*\.{0,1}\d+$/.test(num);
그것을 테스트하려면 :
const isnumeric = (num) => /^-{0,1} \d '{0.} \d +$/.test(num); 함수 testisnumeric () { var 결과 = '' 결과 + = (isnumeric ( '- 1')? "pass": "fail") + ": isnumeric ( '- 1') => true \ n"; 결과 + = (isnumeric ( '- 1.5')? "패스": "실패") + ": isnumeric ( '- 1.5') => true \ n"; 결과 + = (isnumeric ( '0')? "패스": "fail") + ": isnumeric ( '0') => true \ n"; 결과 + = (isnumeric ( '0.42')? "패스": "실패") + ": isnumeric ( '0.42') => true \ n"; 결과 + = (isnumeric ( '. 42')? "pass": "fail") + ": isnumeric ( '. 42') => true \ n"; 결과 + = ('99, 999 ')? "패스": "실패") + ": isnumeric ('99, 999') => false \ n"; 결과 + = ( '0x89F')? "패스": "실패") + ": isnumeric ( '0x89f') => false \ n"; 결과 + = (! IsNumeric ( '# abcdef')? "패스": "실패") + ": isnumeric ( '# abcdef') => false \ n"; 결과 + = (! IsNumeric ( '1.2.3')? "패스": "실패") + ": isnumeric ( '1.2.3') => false \ n"; 결과 + = (isnumeric ( '')? "패스": "실패") + ": isnumeric ( '') => false \ n"; 결과 + = (! isnumeric ( 'blah')? "패스": "fail") + ": isnumeric ( 'blah') => false \ n"; 리턴 결과; } console.log (testisnumeric ()); .as-console-wrapper {최대 - 높이 : 100 %! 중요; TOP : 0; }
나는 http://www.codetoad.com/javascript/isnumeric.asp에서 그 regex를 빌 렸습니다.설명:
/^ match beginning of string
-{0,1} optional negative sign
\d* optional digits
\.{0,1} optional decimal point
\d+ at least one digit
$/ match end of string
답변
허용 된 답변은 당신이 당신의 마음을 바꾸기 때문에 그것이 당신의 테스트 # 7을 실패했습니다.그래서 이것은 내가 문제가있는 수락 된 답변에 대한 반응입니다.
일부 프로젝트 동안 일부 데이터의 유효성을 검사하고 가능한 한 확실한 경우 수학 연산에서 사용할 수있는 JavaScript 숫자 가치입니다.
jQuery 및 일부 다른 JavaScript 라이브러리에는 일반적으로 isNumeric이라고하는 그러한 함수가 이미 포함되어 있습니다.널리 사용 된 답변으로 널리 받아 들여지었던 Stackoverflow에 게시물이 있으며, 전술 한 도서관이 사용하고있는 동일한 일반적인 일상을 사용하고 있습니다.
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
첫째, 위의 코드는 인수가 길이 1의 배열이고 단일 요소는 위의 논리에 의해 숫자로 간주되는 유형이면 true를 반환합니다.제 의견으로는 배열이 아니면 숫자가 아닙니다.
이 문제를 완화하기 위해 논리에서 할인 배열에 대한 수표를 추가했습니다.
function isNumber(n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n);
}
물론 array.isarray, jquery $ .isarray 또는 prototype object.tostring.call (n)! == '[Object Array]'대신 Array.isarray object.isarray를 사용할 수도 있습니다.
내 두 번째 문제는 부정적인 16 진수 정수 리터럴 문자열 ( "-0XA"-> -10)이 숫자로 계산되지 않았다는 것입니다.그러나 양의 16 진수 정수 리터럴 문자열 ( "0xA"-> 10)을 숫자로 처리했습니다. 나는 둘 다 유효한 숫자가 필요했습니다.
그런 다음 논리를 수정하여 이것을 고려해야합니다.
function isNumber(n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}
기능이 호출 될 때마다 정규식 생성에 대해 걱정하는 경우, 이와 같은 폐쇄 내에서 다시 작성할 수 있습니다.
var isNumber = (function () {
var rx = /^-/;
return function (n) {
return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(rx, ''));
};
}());
그런 다음 CMSS +30 테스트 케이스를 가져 와서 JSFIDDLE에서 테스트를 복제 한 내 여분의 테스트 케이스와 위에서 설명한 솔루션을 추가했습니다.
그것은 널리 받아 들여지거나 사용 된 답변을 대체하지 않을 수 있지만 이것이 당신이 isnumeric 함수의 결과로 기대하는 것의 더 많은 것이라면, 이것이 도움이되기를 바랍니다.
편집 : Bergi가 지적한 것처럼 숫자로 간주 될 수있는 다른 물체가 있으며 블랙리스트보다 화이트리스트에게 더 좋을 것입니다.이것을 염두에두고 나는 기준에 추가 할 것입니다.
IsNumeric 함수 만 숫자 또는 문자열 만 고려해주기를 원합니다.
이것을 염두에두고 사용하는 것이 좋습니다.
function isNumber(n) {
return (Object.prototype.toString.call(n) === '[object Number]' || Object.prototype.toString.call(n) === '[object String]') &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}
솔루션을 테스트하십시오
var testHelper = function() { var testSuite = function() { test("Integer Literals", function() { ok(isNumber("-10"), "Negative integer string"); ok(isNumber("0"), "Zero string"); ok(isNumber("5"), "Positive integer string"); ok(isNumber(-16), "Negative integer number"); ok(isNumber(0), "Zero integer number"); ok(isNumber(32), "Positive integer number"); ok(isNumber("040"), "Octal integer literal string"); ok(isNumber(0144), "Octal integer literal"); ok(isNumber("-040"), "Negative Octal integer literal string"); ok(isNumber(-0144), "Negative Octal integer literal"); ok(isNumber("0xFF"), "Hexadecimal integer literal string"); ok(isNumber(0xFFF), "Hexadecimal integer literal"); ok(isNumber("-0xFF"), "Negative Hexadecimal integer literal string"); ok(isNumber(-0xFFF), "Negative Hexadecimal integer literal"); }); test("Foating-Point Literals", function() { ok(isNumber("-1.6"), "Negative floating point string"); ok(isNumber("4.536"), "Positive floating point string"); ok(isNumber(-2.6), "Negative floating point number"); ok(isNumber(3.1415), "Positive floating point number"); ok(isNumber(8e5), "Exponential notation"); ok(isNumber("123e-2"), "Exponential notation string"); }); test("Non-Numeric values", function() { equals(isNumber(""), false, "Empty string"); equals(isNumber(" "), false, "Whitespace characters string"); equals(isNumber("\t\t"), false, "Tab characters string"); equals(isNumber("abcdefghijklm1234567890"), false, "Alphanumeric character string"); equals(isNumber("xabcdefx"), false, "Non-numeric character string"); equals(isNumber(true), false, "Boolean true literal"); equals(isNumber(false), false, "Boolean false literal"); equals(isNumber("bcfed5.2"), false, "Number with preceding non-numeric characters"); equals(isNumber("7.2acdgs"), false, "Number with trailling non-numeric characters"); equals(isNumber(undefined), false, "Undefined value"); equals(isNumber(null), false, "Null value"); equals(isNumber(NaN), false, "NaN value"); equals(isNumber(Infinity), false, "Infinity primitive"); equals(isNumber(Number.POSITIVE_INFINITY), false, "Positive Infinity"); equals(isNumber(Number.NEGATIVE_INFINITY), false, "Negative Infinity"); equals(isNumber(new Date(2009, 1, 1)), false, "Date object"); equals(isNumber(new Object()), false, "Empty object"); equals(isNumber(function() {}), false, "Instance of a function"); equals(isNumber([]), false, "Empty Array"); equals(isNumber(["-10"]), false, "Array Negative integer string"); equals(isNumber(["0"]), false, "Array Zero string"); equals(isNumber(["5"]), false, "Array Positive integer string"); equals(isNumber([-16]), false, "Array Negative integer number"); equals(isNumber([0]), false, "Array Zero integer number"); equals(isNumber([32]), false, "Array Positive integer number"); equals(isNumber(["040"]), false, "Array Octal integer literal string"); equals(isNumber([0144]), false, "Array Octal integer literal"); equals(isNumber(["-040"]), false, "Array Negative Octal integer literal string"); equals(isNumber([-0144]), false, "Array Negative Octal integer literal"); equals(isNumber(["0xFF"]), false, "Array Hexadecimal integer literal string"); equals(isNumber([0xFFF]), false, "Array Hexadecimal integer literal"); equals(isNumber(["-0xFF"]), false, "Array Negative Hexadecimal integer literal string"); equals(isNumber([-0xFFF]), false, "Array Negative Hexadecimal integer literal"); equals(isNumber([1, 2]), false, "Array with more than 1 Positive interger number"); equals(isNumber([-1, -2]), false, "Array with more than 1 Negative interger number"); }); } var functionsToTest = [ function(n) { return !isNaN(parseFloat(n)) && isFinite(n); }, function(n) { return !isNaN(n) && !isNaN(parseFloat(n)); }, function(n) { return !isNaN((n)); }, function(n) { return !isNaN(parseFloat(n)); }, function(n) { return typeof(n) != "boolean" && !isNaN(n); }, function(n) { return parseFloat(n) === Number(n); }, function(n) { return parseInt(n) === Number(n); }, function(n) { return !isNaN(Number(String(n))); }, function(n) { return !isNaN(+('' + n)); }, function(n) { return (+n) == n; }, function(n) { return n && /^-?\d+(\.\d+)?$/.test(n + ''); }, function(n) { return isFinite(Number(String(n))); }, function(n) { return isFinite(String(n)); }, function(n) { return !isNaN(n) && !isNaN(parseFloat(n)) && isFinite(n); }, function(n) { return parseFloat(n) == n; }, function(n) { return (n - 0) == n && n.length > 0; }, function(n) { return typeof n === 'number' && isFinite(n); }, function(n) { return !Array.isArray(n) && !isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, '')); } ]; // Examines the functionsToTest array, extracts the return statement of each function // and fills the toTest select element. var fillToTestSelect = function() { for (var i = 0; i < functionsToTest.length; i++) { var f = functionsToTest[i].toString(); var option = /[\s\S]*return ([\s\S]*);/.exec(f)[1]; $("#toTest").append(''); } } var performTest = function(functionNumber) { reset(); // Reset previous test $("#tests").html(""); //Clean test results isNumber = functionsToTest[functionNumber]; // Override the isNumber global function with the one to test testSuite(); // Run the test // Get test results var totalFail = 0; var totalPass = 0; $("b.fail").each(function() { totalFail += Number($(this).html()); }); $("b.pass").each(function() { totalPass += Number($(this).html()); }); $("#testresult").html(totalFail + " of " + (totalFail + totalPass) + " test failed."); $("#banner").attr("class", "").addClass(totalFail > 0 ? "fail" : "pass"); } return { performTest: performTest, fillToTestSelect: fillToTestSelect, testSuite: testSuite }; }(); $(document).ready(function() { testHelper.fillToTestSelect(); testHelper.performTest(0); $("#toTest").change(function() { testHelper.performTest($(this).children(":selected").val()); }); });
isNumber Test Cases
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11
- Integer Literals (0, 10, 10)
- Foating-Point Literals (0, 6, 6)
- Non-Numeric values (0, 18, 18)
Tests completed in 0 milliseconds.
0 tests of 0 failed.
답변
다음은 죽은 단순한 것입니다 (크롬, 파이어 폭스, 즉, 테스트 됨) :
function isNumeric(x) {
return parseFloat(x) == x;
}
질문의 테스트 케이스 :
console.log('trues');
console.log(isNumeric('-1'));
console.log(isNumeric('-1.5'));
console.log(isNumeric('0'));
console.log(isNumeric('0.42'));
console.log(isNumeric('.42'));
console.log('falses');
console.log(isNumeric('99,999'));
console.log(isNumeric('0x89f'));
console.log(isNumeric('#abcdef'));
console.log(isNumeric('1.2.3'));
console.log(isNumeric(''));
console.log(isNumeric('blah'));
몇 가지 테스트 사례 :
console.log('trues');
console.log(isNumeric(0));
console.log(isNumeric(-1));
console.log(isNumeric(-500));
console.log(isNumeric(15000));
console.log(isNumeric(0.35));
console.log(isNumeric(-10.35));
console.log(isNumeric(2.534e25));
console.log(isNumeric('2.534e25'));
console.log(isNumeric('52334'));
console.log(isNumeric('-234'));
console.log(isNumeric(Infinity));
console.log(isNumeric(-Infinity));
console.log(isNumeric('Infinity'));
console.log(isNumeric('-Infinity'));
console.log('falses');
console.log(isNumeric(NaN));
console.log(isNumeric({}));
console.log(isNumeric([]));
console.log(isNumeric(''));
console.log(isNumeric('one'));
console.log(isNumeric(true));
console.log(isNumeric(false));
console.log(isNumeric());
console.log(isNumeric(undefined));
console.log(isNumeric(null));
console.log(isNumeric('-234aa'));
무한대의 숫자를 고려합니다.
답변
야후!UI는 이것을 사용합니다 :
isNumber: function(o) {
return typeof o === 'number' && isFinite(o);
}
출처:https://stackoverflow.com/questions/18082/validate-decimal-numbers-in-javascript-isnumeric
최근댓글