Wyrażenie regularne liczby dziesiętnej, gdzie cyfra po przecinku jest opcjonalna


112

Potrzebuję wyrażenia regularnego, które sprawdza poprawność liczby, ale nie wymaga cyfry po przecinku. to znaczy.

123
123.
123.4

wszystko będzie ważne

123..

byłby nieważny

Każdy byłby bardzo wdzięczny!


Najlepsza odpowiedź jest tutaj: stackoverflow.com/a/39399503/715269
Gangnus

Odpowiedzi:


190

Użyj następujących:

/^\d*\.?\d*$/
  • ^ - początek linii;
  • \d* - 0 lub więcej cyfr;
  • \.?- Opcjonalna kropka (ze .znakiem ucieczki, ponieważ w wyrażeniu regularnym jest znakiem specjalnym);
  • \d* - 0 lub więcej cyfr (część dziesiętna);
  • $ - Koniec kolejki.

Pozwala to na dziesiętne 0,5 zamiast wymagania wiodącego zera, takiego jak 0,5


2
@OrangeDog, Twoje oryginalne pasują bardziej, niż mogłoby się wydawać. np. „krowa3.45tornado”;)
S. Albano

39
Dopasowuje również pojedynczą kropkę, która nie jest prawidłową liczbą dziesiętną. Lepszym wyrażeniem regularnym byłoby /^\d*\.?\d+$/wymuszenie cyfry po przecinku.
Chandranshu

2
@Chandranshu i dopasowuje pusty ciąg, który również rozwiązałaby twoja zmiana.
OGHaza

2
@Chandranshu „nie wymaga cyfry po przecinku”
OrangeDog,

3
To rozwiązanie nie działa. Wymaga liczb dziesiętnych, podczas gdy OP wyraźnie mówi: opcjonalne liczby dziesiętne.
Alex G

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

Jedna lub więcej cyfr ( \d+), opcjonalna kropka ( \.?), zero lub więcej cyfr ( \d*).

W zależności od zastosowania lub silnika wyrażeń regularnych może być konieczne dodanie kotwic linii początkowej / końcowej:

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

Wizualizacja wyrażeń regularnych

Debuggex Demo


12
Tak, ale najwyżej głosowana odpowiedź jest nieprawidłowa, pasuje do obu .i do pustego ciągu.
OrangeDog,

1
@Gangnus Nie jest też napisane, że „.digit” powinno być dopasowane. Gdyby tego chcieli, powinni byli powiedzieć.
OrangeDog

2
@EqualityInTech Jestem prawie pewien, że tak nie jest - w ogóle nie ma grupowania.
OrangeDog

1
Hmm ... Myślę, że mogę nie w pełni rozumieć złe wyrażenia regularne, tak jak myślałem. Przepraszam.
JDB nadal pamięta Monikę

1
@AlexanderRyanBaggett to dokładnie odpowiada temu, co określono w pytaniu. Jak widać, w ogóle nie zawiera -.
OrangeDog

74

Aby zrobić to poprawnie, potrzebujesz wyrażenia regularnego, takiego jak poniższe:

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

To samo wyrażenie z białymi znakami, przy użyciu rozszerzonego modyfikatora (obsługiwanego przez Perl):

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

lub z komentarzami:

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

Na przykład będzie pasować:

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

I odrzuci te nieliczby:

  • . (pojedynczy punkt dziesiętny)
  • -. (ujemny punkt dziesiętny)
  • +. (plus kropka dziesiętna)
  • (pusta struna)

Prostsze rozwiązania mogą nieprawidłowo odrzucić prawidłowe liczby lub dopasować te nieliczbowe.


1
Najlepsze, ponieważ pasuje do liczby, po której następuje kropka (42.). Istnieje jednak błąd / fałszywie dodatni, ponieważ pasuje do tego: 3 .... 3, który można naprawić, dodając dwa kolejne nawiasy, aby wymusić ^ $ znaki początku i końca: / ^ ([+ -]? (\ D + (\ . \ d *)?) | (\. \ d +)) $ /
Pete Alvin,

1
Dzięki Pete, dobrze zauważony. Odpowiedź została poprawiona przez dodanie dodatkowego nawiasu, aby działała zgodnie z zamierzeniami. Teraz jest napisane jak ^A?(B|C)$. Wcześniej było napisane, ^A?B|C$co właściwie oznacza, (^A?B)|(C$)co było niepoprawne. Uwaga: ^(A?B|C)$jest również niepoprawne, ponieważ w rzeczywistości oznacza, ^((A?B)|(C))$że nie pasuje do „+.5”.
Hoylen,

2
To najlepsza odpowiedź. Inne odpowiedzi nie obejmują wszystkich przypadków. Sam robię podobną rzecz, z wyjątkiem tego, że używam lookahead do obsługi przypadków z brakującymi cyframi: /^[+-]?(?=\d|\.\d)\d*(\.\d*)?$ /
PhilHarvey

1
To jedyne poprawne wyrażenie regularne. Ale niektórzy ludzie nie zgodziliby się z „34.”.
Zaproponowałbym

1
To również pasuje do 0000.2, co prawdopodobnie nie jest pożądane.
Aaron Zorel

11

Wypróbuj to wyrażenie regularne:

\d+\.?\d*

\ d + cyfry przed opcjonalnym dziesiętnym
.? opcjonalny dziesiętny (opcjonalny ze względu na kwantyfikator?)
\ d * opcjonalne cyfry po przecinku


1
Nie, ten nie pasuje123.
Bart Kiers

1
Dzięki za wiadomość. Zmodyfikowałem moje wyrażenie regularne.
Kash

4
Rzeczywiście, ale teraz właśnie zredagowałeś go w to, co zostało już opublikowane przez kogoś innego. Rozważ po prostu usunięcie kolejnej „poprawnej” odpowiedzi.
Bart Kiers

10

Myślę, że ten jest najlepszy, ponieważ spełnia wszystkie wymagania:

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

1
Dla mnie to najlepsza odpowiedź, ponieważ ciąg: „4”. (na przykład) nie jest prawidłową liczbą, przynajmniej w języku ruby. Jednak najczęściej głosowane odpowiedzi przyjmują „4”. jako wyrażenie regularne liczbowe, co jest błędne.
Victor,

3

Skończyło się na tym, że użyłem:

^\d*\.?\d+$

To sprawia, że ​​następujące informacje są nieważne:

.
3.

W zależności od używanego języka możesz potrzebować ukośników. Na przykład: /^\d*\.?\d+$/
Charles

to pozwoli.3
Royi Namir

3

możesz użyć tego:

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

mecze:
11
11,1
0,2

nie pasuje:
.2
2.
2.6.9


Dzięki, bardzo proste i pasuje do tego, czego potrzebuję
Hany


2

To właśnie zrobiłem. Jest bardziej rygorystyczny niż którykolwiek z powyższych (i bardziej poprawny niż niektóre):

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

Ciągi, które przechodzą:

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

Ciągi, które zawodzą:

.
00000
01
.0.
..
00.123
02.134

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

powinien odzwierciedlać to, co ludzie zwykle myślą jako o dobrze sformułowanej liczbie dziesiętnej.

Cyfry przed kropką dziesiętną mogą być jedną cyfrą, w tym przypadku od 0 do 9, lub więcej niż jedną cyfrą, w którym to przypadku nie może zaczynać się od 0.

Jeśli przed znakiem dziesiętnym znajdują się jakieś cyfry, to cyfra dziesiętna i kolejne cyfry są opcjonalne. W przeciwnym razie musi być obecny przecinek, a po nim co najmniej jedna cyfra. Zauważ, że po przecinku dozwolone jest wielokrotne zerowanie na końcu.

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

poprawnie pasuje do następujących:

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

a także ich podpisane odpowiedniki, a odrzuca:

.
00
01
00.0
01.3

i ich podpisane odpowiedniki, a także pusty ciąg.


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

czyste i proste.

Wykorzystuje sufiks i prefiks, funkcje RegEx.

Bezpośrednio zwraca true - false dla warunku IsMatch


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

Przyszedł z tym. Zezwala na liczby całkowite i dziesiętne, ale wymusza pełne miejsce dziesiętne (początkowe i końcowe), jeśli zdecydujesz się wprowadzić liczbę dziesiętną.


1

Na to, o co pytałeś, już odpowiedziano, więc to tylko dodatkowa informacja dla tych, którzy chcą tylko 2 cyfry dziesiętne, jeśli wprowadzono opcjonalny przecinek dziesiętny:

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

^: początek ciągu
\ d: cyfra (równa [0-9])
+: jeden i nieograniczona liczba razy

Grupa przechwytująca (. \ D {2})?
? : zero i jeden raz. : postać .
\ d: cyfra (równa [0-9])
{2}: dokładnie 2 razy
$: koniec ciągu

1: dopasowanie
123: dopasowanie
123.00: dopasowanie
123.: brak dopasowania
123 ..: brak dopasowania
123.0: brak dopasowania
123.000: brak dopasowania
123.00.00: brak dopasowania


Czy to pasuje do liczb ujemnych?
Alexander Ryan Baggett

1
@AlexanderRyanBaggett musisz sprawdzić znak minus, więc byłby to: ^ -? \ D + (\. \ D {2})? $
PersyJack

0

W Perlu użyj Regexp :: Common, który pozwoli ci stworzyć precyzyjnie dostrojone wyrażenie regularne dla twojego konkretnego formatu liczb. Jeśli nie używasz Perla, wygenerowane wyrażenie regularne może być nadal używane w innych językach.

Drukowanie wyniku wygenerowania przykładowych wyrażeń regularnych w 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]+))|))

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.