Espressione regolare numero decimale, dove la cifra dopo il decimale è facoltativa


112

Ho bisogno di un'espressione regolare che convalidi un numero, ma non richiede una cifra dopo il decimale. vale a dire.

123
123.
123.4

sarebbero tutti validi

123..

non sarebbe valido

Qualunque sarebbe molto apprezzato!


La migliore risposta è qui: stackoverflow.com/a/39399503/715269
Gangnus

Risposte:


190

Utilizza il seguente:

/^\d*\.?\d*$/
  • ^ - Inizio della linea;
  • \d* - 0 o più cifre;
  • \.?- Un punto opzionale (con escape, perché in regex, .è un carattere speciale);
  • \d* - 0 o più cifre (la parte decimale);
  • $ - Fine della linea.

Ciò consente di 0,5 decimali anziché richiedere lo zero iniziale, ad esempio 0,5


2
@OrangeDog, le tue corrispondenze originali più di quanto potresti desiderare. es. 'cow3.45tornado';)
S. Albano

39
Corrisponde anche a un singolo punto che non è un numero decimale valido. Una regex migliore sarebbe quella di /^\d*\.?\d+$/forzare una cifra dopo un punto decimale.
Chandranshu

2
@Chandranshu e corrisponde a una stringa vuota, che anche la tua modifica risolverebbe.
OGHaza,

2
@Chandranshu "non richiede una cifra dopo il decimale"
OrangeDog

3
Questa soluzione non funziona. Richiede decimali mentre OP dice chiaramente: decimali opzionali.
Alex G

113
/\d+\.?\d*/

Una o più cifre ( \d+), punto facoltativo ( \.?), zero o più cifre ( \d*).

A seconda dell'utilizzo o del motore regex potrebbe essere necessario aggiungere ancore di linea di inizio / fine:

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

Visualizzazione di espressioni regolari

Debuggex Demo


12
Sì, ma la risposta più votata è sbagliata, corrisponde sia .alla stringa vuota.
OrangeDog

1
@Gangnus Né dice che ".digit" dovrebbe essere abbinato. Se lo volevano, avrebbero dovuto dirlo.
OrangeDog

2
@EqualityInTech Sono abbastanza sicuro che non lo sia - non ha alcun raggruppamento.
OrangeDog

1
Hmm ... Penso che potrei non comprendere appieno le espressioni regolari malvagie come pensavo di aver fatto. Scusate.
JDB ricorda ancora Monica

1
@AlexanderRyanBaggett questo corrisponde esattamente a ciò che la domanda ha specificato. Come puoi vedere non include -affatto.
OrangeDog

74

Hai bisogno di un'espressione regolare come la seguente per farlo correttamente:

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

La stessa espressione con spazi bianchi, utilizzando il modificatore esteso (come supportato da Perl):

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

o con commenti:

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

Ad esempio, corrisponderà a:

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

E rifiuterà questi non numeri:

  • . (punto decimale singolo)
  • -. (punto decimale negativo)
  • +. (più punto decimale)
  • (stringa vuota)

Le soluzioni più semplici possono rifiutare erroneamente numeri validi o abbinare questi non numeri.


1
Migliore perché corrisponde a un numero seguito da un punto (42.). Tuttavia c'è un bug / falso positivo in quanto corrisponde a questo: 3 .... 3 che può essere risolto aggiungendo altre due parentesi per applicare ^ $ caratteri di inizio e fine: / ^ ([+ -]? (\ D + (\ . \ d *)?) | (\. \ d +)) $ /
Pete Alvin,

1
Grazie Pete, ben individuato. La risposta è stata ora corretta, aggiungendo parentesi extra in modo che si comporti come previsto. Ora è scritto come ^A?(B|C)$. In precedenza, era scritto così ^A?B|C$che in realtà significa (^A?B)|(C$)che non era corretto. Nota: ^(A?B|C)$anche questo non è corretto, perché in realtà significa ^((A?B)|(C))$che non corrisponderebbe a "+.5".
Hoylen

2
Questa è la migliore risposta. Le altre risposte non gestiscono tutti i casi. Faccio una cosa simile io stesso, tranne per il fatto che utilizzo un lookahead per gestire i casi con cifre mancanti: /^[+-”?(?=\d|\.\d)\d*(\.\d*)?$ /
PhilHarvey

1
Questa è l'unica regex corretta qui. Ma alcune persone non sarebbero d'accordo con "34.". Proporrei + dopo la seconda d invece di *
Gangnus

1
Questo corrisponde anche a 0000.2, che probabilmente non è ciò che si desidera.
Aaron Zorel

11

Prova questa regex:

\d+\.?\d*

\ d + cifre prima del decimale facoltativo
.? decimale facoltativo (facoltativo a causa del? quantificatore)
\ d * cifre facoltative dopo il decimale


1
No, quello non corrisponde123.
Bart Kiers

1
Grazie per la nota. Modificata la mia regex.
Kash

4
Sì, ma ora l'hai appena modificato in ciò che è già stato pubblicato da qualcun altro. Considera l'idea di rimuovere ancora un'altra risposta "corretta".
Bart Kiers

10

Penso che questo sia il migliore perché soddisfa tutti i requisiti:

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

1
Per me questa è la risposta migliore, poiché la stringa: "4." (per esempio) non è un numero valido almeno in lingua rubino. Tuttavia, le risposte più votate accettano "4". come espressione regolare del numero, il che è sbagliato.
Victor

3

Ho finito per usare quanto segue:

^\d*\.?\d+$

Ciò rende non valido quanto segue:

.
3.

Potresti aver bisogno di barre a seconda della lingua che stai utilizzando. Ad esempio: /^\d*\.?\d+$/
Charles Naccio

questo consentirà.3
Royi Namir

3

puoi usare questo:

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

partite:
11
11.1
0.2

non corrisponde a:
.2
2.
2.6.9


Grazie, molto semplice e corrisponde a ciò di cui ho bisogno
Hany

2

Quale lingua? In stile Perl:^\d+(\.\d*)?$


2

Questo è quello che ho fatto. È più rigoroso di quanto sopra (e più corretto di alcuni):

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

Stringhe che passano:

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

Stringhe che falliscono:

.
00000
01
.0.
..
00.123
02.134

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

dovrebbe riflettere ciò che le persone normalmente pensano come un numero decimale ben formato.

Le cifre prima del punto decimale possono essere una singola cifra, nel qual caso può essere compresa tra 0 e 9, o più di una cifra, nel qual caso non può iniziare con uno 0.

Se sono presenti cifre prima del segno decimale, il decimale e le cifre che seguono sono opzionali. In caso contrario, deve essere presente un decimale seguito da almeno una cifra. Nota che sono consentiti più 0 finali dopo il punto decimale.

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

corrisponde correttamente a quanto segue:

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

così come i loro equivalenti firmati, mentre rifiuta quanto segue:

.
00
01
00.0
01.3

e i loro equivalenti con segno, così come la stringa vuota.


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

pulito e semplice.

Questo utilizza Suffix e Prefix, caratteristiche RegEx.

Restituisce direttamente true - false per la condizione IsMatch


1
^\d+(()|(\.\d+)?)$

È venuto con questo. Consente sia numeri interi che decimali, ma forza un decimale completo (numeri iniziali e finali) se si decide di inserire un decimale.


1

Ciò che hai chiesto ha già una risposta, quindi questa è solo un'informazione aggiuntiva per coloro che vogliono solo 2 cifre decimali se viene inserito il punto decimale opzionale:

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

^: inizio della stringa
\ d: una cifra (uguale a [0-9])
+: una volta e illimitate

Acquisizione del gruppo (. \ D {2})?
? : zero e una volta. : carattere .
\ d: una cifra (uguale a [0-9])
{2}: esattamente 2 volte
$: fine della stringa

1: corrispondenza
123: corrispondenza
123.00: corrispondenza
123.: nessuna corrispondenza
123 ..: nessuna corrispondenza
123.0: nessuna corrispondenza
123.000: nessuna corrispondenza
123.00.00: nessuna corrispondenza


Questo corrisponde a numeri negativi?
Alexander Ryan Baggett

1
@AlexanderRyanBaggett devi controllare il segno negativo, quindi sarebbe: ^ -? \ D + (\. \ D {2})? $
PersyJack

0

In Perl, usa Regexp :: Common che ti permetterà di assemblare un'espressione regolare finemente sintonizzata per il tuo particolare formato numerico. Se non stai usando Perl, l'espressione regolare generata può ancora essere tipicamente usata da altri linguaggi.

Stampa del risultato della generazione delle espressioni regolari di esempio in 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]+))|))

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.