Expression régulière de nombre décimal, où le chiffre après la décimale est facultatif

112

J'ai besoin d'une expression régulière qui valide un nombre, mais ne nécessite pas de chiffre après la décimale. c'est à dire.

123
123.
123.4

serait tout valide

123..

serait invalide

Tout serait grandement apprécié!

Trish
la source
La meilleure réponse est ici: stackoverflow.com/a/39399503/715269
Gangnus

Réponses:

190

Utilisez le suivant:

/^\d*\.?\d*$/
  • ^ - Début de la ligne;
  • \d* - 0 ou plusieurs chiffres;
  • \.?- Un point optionnel (échappé, car dans regex, .est un caractère spécial);
  • \d* - 0 ou plusieurs chiffres (la partie décimale);
  • $ - Fin de la ligne.

Cela permet de 0,5 décimal plutôt que d'exiger le zéro non significatif, tel que 0,5

João Silva
la source
2
@OrangeDog, vos correspondances originales plus que ce que vous souhaiteriez. par exemple 'cow3.45tornado';)
S. Albano
39
Il correspond également à un seul point qui n'est pas un nombre décimal valide. Une meilleure regex serait /^\d*\.?\d+$/qui forcerait un chiffre après un point décimal.
Chandranshu
2
@Chandranshu et il correspond à une chaîne vide, que votre modification résoudrait également.
OGHaza
2
@Chandranshu "n'a pas besoin d'un chiffre après la décimale"
OrangeDog
3
Cette solution ne fonctionne pas. Il nécessite des décimales alors que OP dit clairement: décimales facultatives.
Alex G
113
/\d+\.?\d*/

Un ou plusieurs chiffres ( \d+), point optionnel ( \.?), zéro ou plusieurs chiffres ( \d*).

En fonction de votre utilisation ou de votre moteur d'expression régulière, vous devrez peut-être ajouter des ancres de ligne de début / fin:

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

Visualisation des expressions régulières

Démo Debuggex

OrangeDog
la source
12
Oui, mais la réponse la plus votée est fausse, elle correspond à la fois .et à la chaîne vide.
OrangeDog
1
@Gangnus Il ne dit pas non plus que ".digit" doit correspondre. S'ils le voulaient, ils auraient dû le dire.
OrangeDog
2
@EqualityInTech Je suis presque sûr que ce n'est pas le cas - il n'y a aucun regroupement.
OrangeDog
1
Hmm ... Je pense que je ne comprendrais peut-être pas complètement les mauvaises expressions rationnelles comme je le pensais. Désolé.
JDB se souvient encore de Monica
1
@AlexanderRyanBaggett cela correspond exactement à ce que la question a spécifié. Comme vous pouvez le voir, cela ne comprend pas -du tout.
OrangeDog
74

Vous avez besoin d'une expression régulière comme celle-ci pour le faire correctement:

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

La même expression avec des espaces, en utilisant le modificateur étendu (pris en charge par Perl):

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

ou avec des commentaires:

/^           # 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)

Par exemple, il correspondra:

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

Et rejettera ces non-nombres:

  • . (point décimal unique)
  • -. (point décimal négatif)
  • +. (plus point décimal)
  • (chaîne vide)

Les solutions les plus simples peuvent rejeter à tort des nombres valides ou correspondre à ces non-nombres.

Hoylen
la source
1
Meilleur parce qu'il correspond à un nombre suivi d'un point (42.). Cependant, il y a un bogue / faux positif car il correspond à ceci: 3 .... 3 qui peut être corrigé en ajoutant deux parenthèses supplémentaires pour appliquer ^ $ les caractères de début et de fin: / ^ ([+ -]? (\ D + (\ . \ d *)?) | (\. \ d +)) $ /
Pete Alvin
1
Merci Pete, bien repéré. La réponse a maintenant été corrigée, en ajoutant des parenthèses supplémentaires pour qu'elle se comporte comme prévu. Il est maintenant écrit comme ^A?(B|C)$. Auparavant, il était écrit comme ^A?B|C$ce qui signifie en fait ce (^A?B)|(C$)qui était incorrect. Remarque: ^(A?B|C)$est également incorrect, car cela signifie en fait ^((A?B)|(C))$ce qui ne correspondrait pas à "+.5".
Hoylen
2
C'est la meilleure réponse. Les autres réponses ne traitent pas tous les cas. Je fais une chose similaire moi-même, sauf que j'utilise une anticipation pour gérer les cas de chiffres manquants: /^[+- </font>?(?=\d|\.\d)\d*(\.\d*)?$ /
PhilHarvey
1
C'est le seul regex correct ici. Mais certaines personnes seraient en désaccord avec "34.". Je proposerais + après le deuxième d au lieu de *
Gangnus
1
Cela correspond également à 0000.2, ce qui n'est probablement pas ce que vous souhaitez.
Aaron Zorel
11

Essayez cette expression régulière:

\d+\.?\d*

\ d + chiffres avant la décimale facultative
.? décimal optionnel (optionnel en raison du? quantificateur)
\ d * chiffres optionnels après décimal

Kash
la source
1
Non, celui-là ne correspond pas123.
Bart Kiers
1
Merci pour la note. J'ai modifié mon regex.
Kash
4
En effet, mais maintenant vous venez de le modifier dans ce qui est déjà publié par quelqu'un d'autre. Envisagez simplement de supprimer une autre réponse «correcte».
Bart Kiers
10

Je pense que c'est le meilleur car il répond à toutes les exigences:

^\d+(\\.\d+)?$
Luca Manzo
la source
1
Pour moi, c'est la meilleure réponse, puisque la chaîne: "4." (par exemple) n'est pas un nombre valide au moins en langue rubis. Cependant, les réponses les plus votées acceptent "4". comme une regex numérique, ce qui est faux.
Victor
3

J'ai fini par utiliser ce qui suit:

^\d*\.?\d+$

Cela rend ce qui suit invalide:

.
3.
Charles Naccio
la source
Vous pourriez avoir besoin de barres obliques selon la langue que vous utilisez. Par exemple: /^\d*\.?\d+$/
Charles Naccio
cela permettra.3
Royi Namir
3

vous pouvez utiliser ceci:

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

matchs:
11
11.1
0,2

ne correspond pas:
.2
2.
2.6.9

Ahmed Abdulkafy
la source
Merci, très simple et correspond à ce dont j'ai besoin
Hany
2

Quelle langue? Dans le style Perl:^\d+(\.\d*)?$

Luis
la source
2

C'est ce que j'ai fait. C'est plus strict que tout ce qui précède (et plus correct que certains):

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

Les cordes qui passent:

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

Chaînes qui échouent:

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

devrait refléter ce que les gens considèrent généralement comme un nombre décimal bien formé.

Les chiffres avant la virgule décimale peuvent être soit un seul chiffre, auquel cas il peut être compris entre 0 et 9, soit plusieurs chiffres, auquel cas il ne peut pas commencer par un 0.

S'il y a des chiffres avant le signe décimal, alors le décimal et les chiffres qui le suivent sont facultatifs. Sinon, une décimale doit être présente suivie d'au moins un chiffre. Notez que plusieurs 0 à la fin sont autorisés après la virgule décimale.

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

correspond correctement à ce qui suit:

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

ainsi que leurs équivalents signés, alors qu'il rejette ce qui suit:

.
00
01
00.0
01.3

et leurs équivalents signés, ainsi que la chaîne vide.

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

propre et simple.

Cela utilise le suffixe et le préfixe, les fonctionnalités RegEx.

Il renvoie directement vrai - faux pour la condition IsMatch

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

Je suis venu avec ça. Autorise les nombres entiers et décimaux, mais force une décimale complète (nombres de début et de fin) si vous décidez de saisir une décimale.

cvanniekerk
la source
1

Ce que vous avez demandé est déjà répondu, il ne s'agit donc que d'une information supplémentaire pour ceux qui ne veulent que 2 chiffres décimaux si une virgule décimale facultative est entrée:

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

^: début de la chaîne
\ d: un chiffre (égal à [0-9])
+: une fois et un nombre illimité

Groupe de capture (. \ D {2})?
? : zéro et une fois. : personnage .
\ d: un chiffre (égal à [0-9])
{2}: exactement 2 fois
$: fin de la chaîne

1: correspondance
123: correspondance
123.00: correspondance
123.: pas de correspondance
123 ..: pas de correspondance
123.0: pas de correspondance
123.000: pas de correspondance
123.00.00: pas de correspondance

PersyJack
la source
Cela correspond-il aux nombres négatifs?
Alexander Ryan Baggett
1
@AlexanderRyanBaggett vous devez vérifier le signe négatif pour qu'il soit: ^ -? \ D + (\. \ D {2})? $
PersyJack
0

En Perl, utilisez Regexp :: Common qui vous permettra d'assembler une expression régulière finement ajustée pour votre format numérique particulier. Si vous n'utilisez pas Perl, l'expression régulière générée peut toujours être utilisée par d'autres langages.

Impression du résultat de la génération des exemples d'expressions régulières dans 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
la source
0

essaye ça. ^[0-9]\d{0,9}(\.\d{1,3})?%?$il est testé et a fonctionné pour moi.

Lawrence Eagles
la source