Eu gostaria que o teste mais simples à prova de falhas verifique se uma string em JavaScript é um número inteiro positivo.
isNaN(str)
retorna true para todos os tipos de valores não inteiros e parseInt(str)
está retornando números inteiros para cadeias flutuantes, como "2,5". E não quero ter que usar algum plugin jQuery também.
javascript
Mick Byrne
fonte
fonte
isNaN()
função se comporta da maneira que funciona, porque o conceitoNot a Number
tem um significado muito específico na especificação de ponto flutuante IEEE 794. Não pretende responder à simples pergunta coloquial: "esse valor não é um número?"٢٣٤
ouMCMXIX
são duas representações inteiras válidas, mas não acho que você esteja procurando um código que possa analisá-las. Você pode especificar quais formatos numéricos serão suportados, pois as pessoas parecem confusas sobre isso.Respostas:
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 que0
não seja positivo. Incluo notas se você deseja proibir0
.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:
ou se você deseja permitir espaços em branco e zeros à esquerda:
Cama de teste ao vivo (sem manipular zeros à esquerda ou espaço em branco):
Mostrar snippet de código
Cama de teste ao vivo ( com manipulação para zeros à esquerda e espaços em branco):
Mostrar snippet de código
Se você deseja proibir
0
, mude>= 0
para> 0
. (Ou, na versão que permite zeros à esquerda, remova|| "0"
areplace
linha).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)
: Convertastr
para um número; o número pode muito bem ter uma porção fracionária ou pode serNaN
.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 noString(...)
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,1234567890123456789
falhará). 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 uma0
ou uma string no formato decimal normal:Testbed ao vivo:
Mostrar snippet de código
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|...)
: Permitir0
por conta própria ...(...|[1-9]\d*)
: ... ou um número começando com algo diferente de0
e 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 permitir0
).Se você deseja permitir zeros à esquerda (0123, 00524), substitua a alternação
(?:0|[1-9]\d*)
por\d+
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
+str
ouNumber(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çaparseInt(str, 10)
para garantir que ele seja analisado como decimal (base 10).parseInt
ignoraria o lixo no final da string, mas garantimos que não há nenhum com a regex.fonte
Number(' ')
eNumber('')
return0
while devem retornarNaN
.parseInt
retorna2
./\D/.test('2a')
é verdade (porque não existe um dígito). Então, talvezif (!/\D/.test(str) && !isNan((num = parseInt(str, 10))) { /* Valid number in num */}
... Apenas fora do topo da minha cabeça ...Solução 1
Se considerarmos que um número inteiro JavaScript é o valor máximo
4294967295
(ou sejaMath.pow(2,32)-1
), a seguinte solução curta funcionará perfeitamente:DESCRIÇÃO:
123.45 >>> 0 === 123
-1 >>> 0 === 4294967295
MAX_INT
1e10 >>> 0 === 1410065408
1e7 >>> 0 === 10000000
parseFloat
corrige a análise de números de sequência (configuraçãoNaN
para sequências não numéricas)TESTES:
DEMO: http://jsfiddle.net/5UCy4/37/
Solução 2
Outra maneira é boa para todos os valores numéricos válidos até
Number.MAX_VALUE
, ou seja, aproximadamente1.7976931348623157e+308
:DESCRIÇÃO:
!isNaN(parseFloat(n))
é usado para filtrar puros valores de cadeia, por exemplo""
," "
,"string"
;0 <= ~~n
filtra negativo e valores não inteiros grandes, por exemplo"-40.1"
,"129000098131766699"
;(!isNaN(parseFloat(n)) && 0 <= ~~n)
retornatrue
se o valor é numérico e positivo ;0 === n % (...)
verifica se o valor não é flutuante - aqui(...)
(veja 3) é avaliado como0
no caso defalse
e como1
no caso detrue
.TESTES:
DEMO: http://jsfiddle.net/5UCy4/14/
A versão anterior:
DEMO: http://jsfiddle.net/5UCy4/2/
fonte
~~val
cortar a parte fracionária. É um pouco mais rápido, pois faz uma operação bit a bit em vez de duas.(!isNaN(parseFloat(n)) && n % 1 === 0 && 0 <= ~~n)
true, false, 0xFF
e outros valores passamisPositiveInteger
sem serem detectados.Parece que uma expressão regular é o caminho a seguir:
fonte
0
onde você normalmente não esperaria, mas na maioria das vezes parece bom.A solução moderna que funciona no nó e em mais de 90% de todos os navegadores (exceto o IE e o Opera Mini) é usar o Number.isInteger, seguido de uma verificação positiva simples.
Isso foi finalizado no ECMAScript 2015 .
O Polyfil é:
Se você precisar dar suporte à entrada que possa estar na forma de sequência ou número , poderá usar esta função contra a qual escrevi uma grande suíte de testes depois que todas as respostas existentes (01/02/2018) falharam em alguma forma de entrada.
fonte
Esta é quase uma pergunta duplicada para esta:
Validar números decimais em JavaScript - IsNumeric ()
Sua resposta é:
portanto, um número inteiro positivo seria:
fonte
não funcionará se você der uma string como '0001'
fonte
Minha função verifica se o número é + ve e também pode ter valor decimal.
fonte
Apenas para aproveitar a resposta do VisioN acima, se você estiver usando o plugin de validação jQuery, poderá usar o seguinte:
Em seguida, você pode usar em seu conjunto de regras normal ou adicioná-lo dinamicamente da seguinte maneira:
fonte
Simples
Você também pode estender o número e atribuir a função a ele via protótipo.
fonte
Se você estiver usando formulários HTML5, poderá usar o atributo
min="0"
para o elemento do formulário<input type="number" />
. Isso é suportado por todos os principais navegadores. Não envolve Javascript para tarefas simples, mas está integrado no novo padrão html. Está documentado em https://www.w3schools.com/tags/att_input_min.aspfonte
(~~a == a)
ondea
está a stringfonte
~~"-1" == "-1"
retornarátrue
. E o OP pediu apenas números inteiros positivos.ES6:
fonte