Duas respostas para você:
Com base na análise
Expressão regular
Observe que nos dois casos, interpretei "número inteiro positivo" para incluir 0, mesmo que 0não seja positivo. Incluo notas se você deseja proibir 0.
Baseado na análise
Se você deseja que ela seja uma sequência inteira decimal normalizada em um intervalo razoável de valores, faça o seguinte:
function isNormalInteger(str) {
var n = Math.floor(Number(str));
return n !== Infinity && String(n) === str && n >= 0;
}
ou se você deseja permitir espaços em branco e zeros à esquerda:
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;
}
Cama de teste ao vivo (sem manipular zeros à esquerda ou espaço em branco):
function isNormalInteger(str) {
var n = Math.floor(Number(str));
return n !== Infinity && String(n) === str && n >= 0;
}
function gid(id) {
return document.getElementById(id);
}
function test(str, expect) {
var result = isNormalInteger(str);
console.log(
str + ": " +
(result ? "Yes" : "No") +
(expect === undefined ? "" : !!expect === !!result ? " <= OK" : " <= ERROR ***")
);
}
gid("btn").addEventListener(
"click",
function() {
test(gid("text").value);
},
false
);
test("1", true);
test("1.23", false);
test("1234567890123", true);
test("1234567890123.1", false);
test("0123", false); // false because we don't handle leading 0s
test(" 123 ", false); // false because we don't handle whitespace
<label>
String:
<input id="text" type="text" value="">
<label>
<input id="btn" type="button" value="Check">
Cama de teste ao vivo ( com manipulação para zeros à esquerda e espaços em branco):
function isNormalInteger(str) {
str = str.trim();
if (!str) {
return false;
}
str = str.replace(/^0+/, "") || "0";
var n = Math.floor(Number(str));
return String(n) === str && n >= 0;
}
function gid(id) {
return document.getElementById(id);
}
function test(str, expect) {
var result = isNormalInteger(str);
console.log(
str + ": " +
(result ? "Yes" : "No") +
(expect === undefined ? "" : !!expect === !!result ? " <= OK" : " <= ERROR ***")
);
}
gid("btn").addEventListener(
"click",
function() {
test(gid("text").value);
},
false
);
test("1", true);
test("1.23", false);
test("1234567890123", true);
test("1234567890123.1", false);
test("0123", true);
test(" 123 ", true);
<label>
String:
<input id="text" type="text" value="">
<label>
<input id="btn" type="button" value="Check">
Se você deseja proibir 0, mude >= 0para > 0. (Ou, na versão que permite zeros à esquerda, remova || "0"a replacelinha).
Como isso funciona:
Na versão que permite espaços em branco e zeros à esquerda:
str = str.trim(); remove qualquer espaço em branco inicial e final.
if (!str) pega uma string em branco e retorna, não adianta fazer o resto do trabalho.
str = str.replace(/^0+/, "") || "0"; remove todos os 0s iniciais da sequência - mas se isso resultar em uma sequência em branco, restaura um único 0.
Number(str): Converta strpara um número; o número pode muito bem ter uma porção fracionária ou pode ser NaN.
Math.floor: Trunca o número (corta qualquer parte fracionária).
String(...): Converte o resultado novamente em uma seqüência decimal normal. Para números realmente grandes, isso vai para notação científica, que pode quebrar essa abordagem. (Não sei exatamente onde está a divisão, os detalhes estão nas especificações , mas para números inteiros acredito que esteja no ponto em que você excedeu 21 dígitos [quando o número se tornou muito impreciso, como IEEE-754 números de precisão dupla têm apenas 15 dígitos de precisão ..)
... === str: Compara isso à string original.
n >= 0: Verifique se é positivo.
Observe que isso falha na entrada "+1", qualquer entrada na notação científica que não volte à mesma notação científica no String(...)estágio e por qualquer valor que o tipo de número que o JavaScript use (ponto flutuante binário de precisão dupla IEEE-754) não é possível representar com precisão o que é mais próximo de um valor diferente do valor especificado (que inclui muitos números inteiros acima de 9.007.199.254.740.992; por exemplo, 1234567890123456789falhará). O primeiro é uma solução fácil, os dois últimos nem tanto.
Expressão regular
A outra abordagem é testar os caracteres da string por meio de uma expressão regular, se seu objetivo é permitir (digamos) apenas um opcional +seguido por uma 0ou uma string no formato decimal normal:
function isNormalInteger(str) {
return /^\+?(0|[1-9]\d*)$/.test(str);
}
Testbed ao vivo:
function isNormalInteger(str) {
return /^\+?(0|[1-9]\d*)$/.test(str);
}
function gid(id) {
return document.getElementById(id);
}
function test(str, expect) {
var result = isNormalInteger(str);
console.log(
str + ": " +
(result ? "Yes" : "No") +
(expect === undefined ? "" : !!expect === !!result ? " <= OK" : " <= ERROR ***")
);
}
gid("btn").addEventListener(
"click",
function() {
test(gid("text").value);
},
false
);
test("1", true);
test("1.23", false);
test("1234567890123", true);
test("1234567890123.1", false);
test("0123", false); // false because we don't handle leading 0s
test(" 123 ", false); // false because we don't handle whitespace
<label>
String:
<input id="text" type="text" value="">
<label>
<input id="btn" type="button" value="Check">
Como isso funciona:
^: Corresponde ao início da sequência
\+?: Permita um único, opcional +(remova-o se não desejar)
(?:...|...): Permita uma dessas duas opções (sem criar um grupo de captura):
(0|...): Permitir 0por conta própria ...
(...|[1-9]\d*): ... ou um número começando com algo diferente de 0e seguido por qualquer número de dígitos decimais.
$: Corresponde ao final da string.
Se você deseja proibir 0(porque não é positivo), a expressão regular se torna justa /^\+?[1-9]\d*$/(por exemplo, podemos perder a alternância que precisávamos permitir 0).
Se você deseja permitir zeros à esquerda (0123, 00524), substitua a alternação (?:0|[1-9]\d*)por\d+
function isNormalInteger(str) {
return /^\+?\d+$/.test(str);
}
Se você deseja permitir espaço em branco, adicione \s*logo após ^e \s*pouco antes $.
Observe quando você converte isso em um número: em mecanismos modernos, provavelmente seria bom usá-lo +strou Number(str)fazê-lo, mas os mais antigos podem estendê-los de uma maneira não-padrão (mas anteriormente permitida) que diz que um zero à esquerda significa octal (base 8), por exemplo, "010" => 8. Depois de validar o número, você pode usá-lo com segurança parseInt(str, 10)para garantir que ele seja analisado como decimal (base 10). parseIntignoraria o lixo no final da string, mas garantimos que não há nenhum com a regex.