Me gustaría que la prueba más simple a prueba de fallas verifique que una cadena en JavaScript sea un entero positivo.
isNaN(str)
devuelve verdadero para todo tipo de valores no enteros y parseInt(str)
devuelve enteros para cadenas flotantes, como "2.5". Y tampoco quiero tener que usar algún complemento jQuery.
javascript
Mick Byrne
fuente
fuente
isNaN()
función se comporta como lo hace porque el conceptoNot a Number
tiene un significado muy específico en la especificación de coma flotante IEEE 794. No tiene la intención de proporcionar una respuesta a la simple pregunta coloquial, "¿este valor no es un número?"٢٣٤
oMCMXIX
ambas son representaciones enteras válidas, pero no creo que esté buscando un código que pueda analizarlas. ¿Podría especificar qué formatos de números admitirá, ya que la gente parece confundida al respecto?Respuestas:
Dos respuestas para ti:
Basado en análisis
Expresión regular
Tenga en cuenta que en ambos casos, he interpretado "entero positivo" para incluir
0
, aunque0
no es positivo. Incluyo notas si desea no permitir0
.Basado en análisis
Si desea que sea una cadena entera decimal normalizada en un rango razonable de valores, puede hacer esto:
o si desea permitir espacios en blanco y ceros a la izquierda:
Banco de pruebas en vivo (sin manejar ceros a la izquierda o espacios en blanco):
Mostrar fragmento de código
Banco de pruebas en vivo ( con manejo de ceros y espacios en blanco):
Mostrar fragmento de código
Si desea rechazar
0
, simplemente cambie>= 0
a> 0
. (O, en la versión que permite los ceros a la izquierda, elimine el|| "0"
en lareplace
línea).Cómo funciona eso:
En la versión que permite espacios en blanco y ceros a la izquierda:
str = str.trim();
elimina cualquier espacio en blanco inicial y final.if (!str)
atrapa una cadena en blanco y regresa, no tiene sentido hacer el resto del trabajo.str = str.replace(/^0+/, "") || "0";
elimina todos los 0 iniciales de la cadena, pero si eso resulta en una cadena en blanco, restaura un solo 0.Number(str)
: Convertirstr
a un número; el número bien puede tener una porción fraccional, o puede serNaN
.Math.floor
: Trunca el número (corta cualquier porción fraccional).String(...)
: Convierte el resultado nuevamente en una cadena decimal normal. Para números realmente grandes, esto irá a notación científica, lo que puede romper este enfoque. (No sé exactamente dónde está la división, los detalles están en la especificación , pero para los números enteros creo que es en el momento en que has excedido los 21 dígitos [en ese momento el número se ha vuelto muy impreciso, como IEEE-754 los números de doble precisión solo tienen 15 dígitos precisos de precisión ...)... === str
: Compara eso con la cadena original.n >= 0
: Comprueba que sea positivo.Tenga en cuenta que esto falla para la entrada
"+1"
, cualquier entrada en notación científica que no se convierta en la misma notación científica en laString(...)
etapa, y para cualquier valor que utilice el tipo de número que JavaScript utiliza (punto flotante binario de doble precisión IEEE-754) no puede representar con precisión qué análisis está más cerca de un valor diferente que el dado (que incluye muchos enteros de más de 9,007,199,254,740,992; por ejemplo,1234567890123456789
fallará). El primero es una solución fácil, los dos últimos no tanto.Expresión regular
El otro enfoque es probar los caracteres de la cadena a través de una expresión regular, si su objetivo es permitir (digamos) una opción
+
seguida por una0
o una cadena en formato decimal normal:Banco de pruebas en vivo:
Mostrar fragmento de código
Cómo funciona eso:
^
: Inicio de la secuencia del partido\+?
: Permitir un solo, opcional+
(elimine esto si no lo desea)(?:...|...)
: Permita una de estas dos opciones (sin crear un grupo de captura):(0|...)
: Permitir0
por sí solo ...(...|[1-9]\d*)
: ... o un número que comienza con algo diferente0
y seguido de cualquier número de dígitos decimales.$
: Coincide con el final de la cadena.Si desea rechazar
0
(porque no es positivo), la expresión regular se vuelve justa/^\+?[1-9]\d*$/
(por ejemplo, podemos perder la alternancia que necesitábamos permitir0
).Si desea permitir ceros a la izquierda (0123, 00524), simplemente reemplace la alternancia
(?:0|[1-9]\d*)
con\d+
Si desea permitir espacios en blanco, agregue
\s*
justo después^
y\s*
justo antes$
.Nota para cuando convierta eso en un número: en los motores modernos probablemente estaría bien usarlo
+str
oNumber(str)
hacerlo, pero los más antiguos podrían extenderlos de una manera no estándar (pero permitida anteriormente) que dice que un cero inicial significa octal (base 8), por ejemplo, "010" => 8. Una vez que haya validado el número, puede usarloparseInt(str, 10)
con seguridad para asegurarse de que se analiza como decimal (base 10).parseInt
ignoraría la basura al final de la cadena, pero nos hemos asegurado de que no haya ninguna con la expresión regular.fuente
Number(' ')
yNumber('')
regresar0
mientras debería regresarNaN
en su lugarparseInt
regresa2
./\D/.test('2a')
es cierto (porque hay un no dígito). Entonces, tal vezif (!/\D/.test(str) && !isNan((num = parseInt(str, 10))) { /* Valid number in num */}
... justo en la parte superior de mi cabeza ...Solución 1
Si consideramos que un entero JavaScript es un valor máximo
4294967295
(es decirMath.pow(2,32)-1
), entonces la siguiente solución breve funcionará perfectamente:DESCRIPCIÓN:
123.45 >>> 0 === 123
-1 >>> 0 === 4294967295
MAX_INT
1e10 >>> 0 === 1410065408
1e7 >>> 0 === 10000000
parseFloat
realiza un análisis correcto de los números de cadena (configuraciónNaN
para cadenas no numéricas)PRUEBAS
DEMO: http://jsfiddle.net/5UCy4/37/
Solución 2
Otra forma es buena para todos los valores numéricos que son válidos hasta
Number.MAX_VALUE
, es decir, aproximadamente1.7976931348623157e+308
:DESCRIPCIÓN:
!isNaN(parseFloat(n))
se utiliza para filtrar puros valores de cadena, por ejemplo""
," "
,"string"
;0 <= ~~n
filtra negativo y valores no enteros grandes, por ejemplo"-40.1"
,"129000098131766699"
;(!isNaN(parseFloat(n)) && 0 <= ~~n)
devuelvetrue
si el valor es tanto numérico como positivo ;0 === n % (...)
comprueba si el valor no es flotante - aquí(...)
(ver 3) se evalúa como0
en el caso defalse
, y como1
en el caso detrue
.PRUEBAS
DEMO: http://jsfiddle.net/5UCy4/14/
La versión anterior:
DEMO: http://jsfiddle.net/5UCy4/2/
fuente
~~val
cortar la parte fraccionaria. Es un poco más rápido ya que realiza una operación bit a bit en lugar de dos.(!isNaN(parseFloat(n)) && n % 1 === 0 && 0 <= ~~n)
true, false, 0xFF
, y otros valores logran pasarisPositiveInteger
sin ser detectados.Parece que una expresión regular es el camino a seguir:
fuente
0
donde normalmente no esperarías, pero en su mayor parte, parece estar bien.La solución moderna que funciona en el nodo y en más del 90% de todos los navegadores (excepto IE y Opera Mini) es usar Number.isInteger seguido de una simple verificación positiva.
Esto se finalizó en ECMAScript 2015 .
El Polyfil es:
Si necesita admitir entradas que pueden estar en forma de cadena o número, entonces puede usar esta función contra la que escribí un gran conjunto de pruebas después de que todas las respuestas existentes (2/1/2018) fallaron en alguna forma de entrada.
fuente
Esta es casi una pregunta duplicada para esta:
Validar números decimales en JavaScript - IsNumeric ()
Su respuesta es:
entonces, un entero positivo sería:
fuente
aunque no funcionará si le das una cadena como '0001'
fuente
Mi función verifica si el número es + ve y también podría tener un valor decimal.
fuente
Solo para construir sobre la respuesta de VisioN anterior, si está utilizando el complemento de validación jQuery, podría usar esto:
Luego, podría usar en su conjunto de reglas normales o agregarlo dinámicamente de esta manera:
fuente
Sencillo
También puede extender Número y asignarle la función a través de un prototipo.
fuente
Si está utilizando formularios HTML5, puede usar el atributo
min="0"
para el elemento del formulario<input type="number" />
. Esto es compatible con todos los principales navegadores. No implica Javascript para tareas tan simples, pero está integrado en el nuevo estándar html. Está documentado en https://www.w3schools.com/tags/att_input_min.aspfuente
(~~a == a)
dondea
esta la cuerdafuente
~~"-1" == "-1"
volverátrue
. Y OP solo pidió enteros positivos.ES6:
fuente