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!


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


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


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.


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


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+)?$

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

puedes usar esto:

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

partidos:
11
11,1
0,2

no coincide:
.2
2.
2.6.9


Gracias, muy simple y coincide con lo que necesito
Hany

2

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


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

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.


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


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.


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


¿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]+))|))

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.