Expresión regular de número decimal, donde el dígito después del decimal es opcional

112

Necesito una expresión regular que valide un número, pero no requiere un dígito después del decimal. es decir.

123
123.
123.4

todo sería válido

123..

sería inválido

¡Cualquiera sería muy apreciado!

Trish
fuente
La mejor respuesta está aquí: stackoverflow.com/a/39399503/715269
Gangnus

Respuestas:

190

Utilice lo siguiente:

/^\d*\.?\d*$/
  • ^ - Comienzo de la línea;
  • \d* - 0 o más dígitos;
  • \.?- Un punto opcional (escapado, porque en regex, .es un carácter especial);
  • \d* - 0 o más dígitos (la parte decimal);
  • $ - Final de la línea.

Esto permite 0.5 decimal en lugar de requerir el cero inicial, como 0.5

João Silva
fuente
2
@OrangeDog, sus coincidencias originales más de lo que podría desear. por ejemplo, 'vaca3.45tornado';)
S. Albano
39
También coincide con un solo punto que no es un número decimal válido. Una expresión regular mejor sería la /^\d*\.?\d+$/que forzaría un dígito después de un punto decimal.
Chandranshu
2
@Chandranshu y coincide con una cadena vacía, que su cambio también resolvería.
OGHaza
2
@Chandranshu "no requiere un dígito después del decimal"
OrangeDog
3
Esta solución no funciona. Requiere decimales, mientras que OP dice claramente: decimales opcionales.
Alex G
113
/\d+\.?\d*/

Uno o más dígitos ( \d+), punto opcional ( \.?), cero o más dígitos ( \d*).

Dependiendo de su uso o motor de expresiones regulares, es posible que deba agregar anclajes de línea de inicio / fin:

/^\d+\.?\d*$/

Visualización de expresiones regulares

Demostración de Debuggex

OrangeDog
fuente
12
Sí, pero la respuesta más votada es incorrecta, coincide con ambos .y la cadena vacía.
OrangeDog
1
@Gangnus Tampoco dice que ".digit" deba coincidir. Si querían eso, deberían haberlo dicho.
OrangeDog
2
@EqualityInTech Estoy bastante seguro de que no lo es, no tiene ninguna agrupación.
OrangeDog
1
Hmm ... creo que no puedo entender completamente las expresiones regulares malignas como pensaba. Lo siento.
JDB todavía recuerda a Monica
1
@AlexanderRyanBaggett esto coincide exactamente con lo que especificó la pregunta. Como puede ver, no incluye -nada.
OrangeDog
74

Necesita una expresión regular como la siguiente para hacerlo correctamente:

/^[+-]?((\d+(\.\d*)?)|(\.\d+))$/

La misma expresión con espacios en blanco, usando el modificador extendido (compatible con Perl):

/^  [+-]? ( (\d+ (\.\d*)?)  |  (\.\d+) ) $/x

o con comentarios:

/^           # Beginning of string
 [+-]?       # Optional plus or minus character
 (           # Followed by either:
   (           #   Start of first option
     \d+       #   One or more digits
     (\.\d*)?  #   Optionally followed by: one decimal point and zero or more digits
   )           #   End of first option
   |           # or
   (\.\d+)     #   One decimal point followed by one or more digits
 )           # End of grouping of the OR options
 $           # End of string (i.e. no extra characters remaining)
 /x          # Extended modifier (allows whitespace & comments in regular expression)

Por ejemplo, coincidirá con:

  • 123
  • 23.45
  • 34.
  • .45
  • -123
  • -273,15
  • -42.
  • -.45
  • +516
  • +9,8
  • +2.
  • +.5

Y rechazará estos no números:

  • . (punto decimal único)
  • -. (punto decimal negativo)
  • +. (más el punto decimal)
  • (cuerda vacía)

Las soluciones más simples pueden rechazar incorrectamente números válidos o hacer coincidir estos no números.

Hoylen
fuente
1
Mejor porque coincide con un número seguido de un punto (42). Sin embargo, hay un error / falso positivo ya que coincide con esto: 3 .... 3 que se puede solucionar agregando dos paréntesis más para hacer cumplir ^ $ caracteres de inicio y final: / ^ ([+ -]? (\ D + (\ . \ d *)?) | (\. \ d +)) $ /
Pete Alvin
1
Gracias Pete, bien visto. La respuesta ahora se ha corregido, agregando paréntesis adicionales para que se comporte como se esperaba. Ahora está escrito como ^A?(B|C)$. Anteriormente, estaba escrito como lo ^A?B|C$que en realidad significa (^A?B)|(C$)que era incorrecto. Nota: ^(A?B|C)$también es incorrecta, porque en realidad significa ^((A?B)|(C))$que no coincidiría con "+.5".
Hoylen
2
Esta es la mejor respuesta. Las otras respuestas no manejan todos los casos. Yo mismo hago algo similar, excepto que uso una búsqueda anticipada para manejar los casos de dígitos faltantes: /^[+-]?(?=\d|\.\d)\d*(\.\d*)?$ /
PhilHarvey
1
Esa es la única expresión regular correcta aquí. Pero algunas personas no estarían de acuerdo con "34". Propondría + después de la segunda d en lugar de *
Gangnus
1
Esto también coincide con 0000.2, que probablemente no sea lo que se desea.
Aaron Zorel
11

Prueba esta expresión regular:

\d+\.?\d*

\ d + dígitos antes del decimal opcional
.? decimal opcional (opcional debido al cuantificador?)
\ d * dígitos opcionales después del decimal

Kash
fuente
1
No, ese no coincide123.
Bart Kiers
1
Gracias por la nota. Modificó mi expresión regular.
Kash
4
De hecho, pero ahora lo acaba de editar en lo que ya ha publicado otra persona. Considere simplemente eliminar otra respuesta "correcta".
Bart Kiers
10

Creo que este es el mejor porque cumple con todos los requisitos:

^\d+(\\.\d+)?$
Luca Manzo
fuente
1
Para mí, esta es la mejor respuesta, ya que la cadena: "4". (por ejemplo) no es un número válido al menos en lenguaje rubí. Sin embargo, las respuestas más votadas aceptan "4". como una expresión regular numérica, lo cual es incorrecto.
Victor
3

Terminé usando lo siguiente:

^\d*\.?\d+$

Esto invalida lo siguiente:

.
3.
Charles Naccio
fuente
Es posible que necesite barras según el idioma que esté usando. Por ejemplo: /^\d*\.?\d+$/
Charles Naccio
esto permitirá.3
Royi Namir
3

puedes usar esto:

^\d+(\.\d)?\d*$

partidos:
11
11,1
0,2

no coincide:
.2
2.
2.6.9

Ahmed Abdulkafy
fuente
Gracias, muy simple y coincide con lo que necesito
Hany
2

¿Que lenguaje? En estilo Perl:^\d+(\.\d*)?$

Luis
fuente
2

Esto es lo que hice. Es más estricto que cualquiera de los anteriores (y más correcto que algunos):

^0$|^[1-9]\d*$|^\.\d+$|^0\.\d*$|^[1-9]\d*\.\d*$

Cuerdas que pasa:

0
0.
1
123
123.
123.4
.0
.0123
.123
0.123
1.234
12.34

Cuerdas que falla:

.
00000
01
.0.
..
00.123
02.134
Xiaohang James Miao
fuente
2
^[+-]?(([1-9][0-9]*)?[0-9](\.[0-9]*)?|\.[0-9]+)$

debe reflejar lo que la gente suele considerar un número decimal bien formado.

Los dígitos antes del punto decimal pueden ser de un solo dígito, en cuyo caso puede ser de 0 a 9, o más de un dígito, en cuyo caso no puede comenzar con un 0.

Si hay dígitos antes del signo decimal, entonces el decimal y los dígitos siguientes son opcionales. De lo contrario, debe haber un decimal seguido de al menos un dígito. Tenga en cuenta que se permiten varios ceros finales después del punto decimal.

grep -E '^[+-]?(([1-9][0-9]*)?[0-9](\.[0-9]*)?|\.[0-9]+)$'

coincide correctamente con lo siguiente:

9
0
10
10.
0.
0.0
0.100
0.10
0.01
10.0
10.10
.0
.1
.00
.100
.001

así como sus equivalentes firmados, mientras que rechaza lo siguiente:

.
00
01
00.0
01.3

y sus equivalentes firmados, así como la cadena vacía.

Aaron Zorel
fuente
1
(?<![^d])\d+(?:\.\d+)?(?![^d])

limpio y sencillo.

Esto utiliza características RegEx de sufijo y prefijo.

Devuelve directamente verdadero - falso para la condición IsMatch

Prashant P
fuente
1
^\d+(()|(\.\d+)?)$

Se me ocurrió esto. Permite tanto números enteros como decimales, pero fuerza un decimal completo (números iniciales y finales) si decide ingresar un decimal.

cvanniekerk
fuente
1

Lo que preguntaste ya está respondido, por lo que esta es solo una información adicional para aquellos que desean solo 2 dígitos decimales si se ingresa un punto decimal opcional:

^\d+(\.\d{2})?$

^: inicio de la cadena
\ d: un dígito (igual a [0-9])
+: uno y tiempos ilimitados

¿Grupo de captura (. \ D {2})?
? : cero y uno veces. : personaje .
\ d: un dígito (igual a [0-9])
{2}: exactamente 2 veces
$: final de la cadena

1: coincidencia
123: coincidencia
123.00: coincidencia
123.: no coincide
123 ...: no coincide
123.0: no coincide
123.000: no coincide
123.00.00: no coincide

PersyJack
fuente
¿Coincide esto con números negativos?
Alexander Ryan Baggett
1
@AlexanderRyanBaggett, debe verificar el signo negativo para que sea: ^ -? \ D + (\. \ D {2})? $
PersyJack
0

En Perl, use Regexp :: Common que le permitirá ensamblar una expresión regular finamente ajustada para su formato de número particular. Si no está utilizando Perl, la expresión regular generada todavía puede ser utilizada por otros lenguajes.

Imprimir el resultado de generar las expresiones regulares de ejemplo en Regexp :: Common :: Number:

$ perl -MRegexp::Common=number -E 'say $RE{num}{int}'
(?:(?:[-+]?)(?:[0123456789]+))

$ perl -MRegexp::Common=number -E 'say $RE{num}{real}'
(?:(?i)(?:[-+]?)(?:(?=[.]?[0123456789])(?:[0123456789]*)(?:(?:[.])(?:[0123456789]{0,}))?)(?:(?:[E])(?:(?:[-+]?)(?:[0123456789]+))|))

$ perl -MRegexp::Common=number -E 'say $RE{num}{real}{-base=>16}'
(?:(?i)(?:[-+]?)(?:(?=[.]?[0123456789ABCDEF])(?:[0123456789ABCDEF]*)(?:(?:[.])(?:[0123456789ABCDEF]{0,}))?)(?:(?:[G])(?:(?:[-+]?)(?:[0123456789ABCDEF]+))|))
pndc
fuente
0

prueba esto. ^[0-9]\d{0,9}(\.\d{1,3})?%?$está probado y funcionó para mí.

Lawrence Eagles
fuente