Ekspresi reguler angka desimal, dengan digit setelah desimal adalah opsional


112

Saya memerlukan ekspresi reguler yang memvalidasi angka, tetapi tidak memerlukan angka setelah desimal. yaitu.

123
123.
123.4

semuanya akan valid

123..

akan menjadi tidak valid

Apa pun akan sangat dihargai!


Jawaban terbaik ada di sini: stackoverflow.com/a/39399503/715269
Gangnus

Jawaban:


190

Gunakan yang berikut ini:

/^\d*\.?\d*$/
  • ^ - Awal baris;
  • \d* - 0 atau lebih digit;
  • \.?- Titik opsional (di-escape, karena dalam regex, .adalah karakter khusus);
  • \d* - 0 atau lebih digit (bagian desimal);
  • $ - Akhir garis.

Ini memungkinkan untuk 0,5 desimal daripada membutuhkan nol di depannya, seperti 0,5


2
@OrangeDog, kecocokan orisinal Anda lebih dari yang mungkin diinginkan. misalnya 'cow3.45tornado';)
S. Albano

39
Ini juga cocok dengan satu titik yang bukan merupakan angka desimal yang valid. Regex yang lebih baik /^\d*\.?\d+$/akan memaksa angka setelah koma desimal.
Chandranshu

2
@Chandranshu dan itu cocok dengan string kosong, yang juga akan menyelesaikan perubahan Anda.
OGHaza

2
@Chandranshu "tidak memerlukan digit setelah desimal"
OrangeDog

3
Solusi ini tidak berhasil. Ini membutuhkan desimal sementara OP dengan jelas mengatakan: desimal opsional.
Alex G

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

Satu atau lebih digit ( \d+), titik opsional ( \.?), nol atau lebih digit ( \d*).

Bergantung pada penggunaan atau mesin regex Anda, Anda mungkin perlu menambahkan jangkar garis awal / akhir:

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

Visualisasi ekspresi reguler

Demo Debuggex


12
Ya, tetapi jawaban pilihan teratas salah, itu cocok .dengan string kosong dan keduanya .
OrangeDog

1
@Gangnus Juga tidak mengatakan bahwa ".digit" harus dicocokkan. Jika mereka menginginkan itu, maka mereka seharusnya mengatakannya.
OrangeDog

2
@EqualityInTech Saya cukup yakin tidak - tidak ada pengelompokan sama sekali.
OrangeDog

1
Hmm ... Saya pikir saya mungkin tidak sepenuhnya memahami ekspresi reguler seperti yang saya kira. Maaf.
JDB masih mengingat Monica

1
@AlexanderRyanBaggett ini sama persis dengan pertanyaan yang ditentukan. Seperti yang Anda lihat, itu tidak termasuk -sama sekali.
OrangeDog

74

Anda memerlukan ekspresi reguler seperti berikut untuk melakukannya dengan benar:

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

Ekspresi yang sama dengan spasi, menggunakan pengubah diperpanjang (seperti yang didukung oleh Perl):

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

atau dengan komentar:

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

Misalnya, ini akan cocok dengan:

  • 123
  • 23.45
  • 34.
  • .45
  • -123
  • -273.15
  • -42.
  • -.45
  • +516
  • +9.8
  • +2.
  • +.5

Dan akan menolak non-angka ini:

  • . (satu koma desimal)
  • -. (titik desimal negatif)
  • +. (ditambah koma desimal)
  • (string kosong)

Solusi yang lebih sederhana dapat salah menolak angka yang valid atau mencocokkan bukan angka ini.


1
Terbaik karena cocok dengan angka yang diikuti oleh titik (42.). Namun ada bug / false positive karena cocok dengan ini: 3 .... 3 yang dapat diperbaiki dengan menambahkan dua tanda kurung lagi untuk memaksakan ^ $ karakter awal dan akhir: / ^ ([+ -]? (\ D + (\ . \ d *)?) | (\. \ d +)) $ /
Pete Alvin

1
Terima kasih Pete, terlihat bagus. Jawabannya sekarang telah dikoreksi, dengan menambahkan tanda kurung ekstra sehingga berfungsi sebagaimana mestinya. Sekarang ditulis seperti ^A?(B|C)$. Sebelumnya, ditulis seperti ^A?B|C$yang sebenarnya berarti (^A?B)|(C$)mana yang salah. Catatan: ^(A?B|C)$juga salah, karena itu sebenarnya berarti ^((A?B)|(C))$mana yang tidak cocok dengan "+.5".
Hoylen

2
Ini jawaban terbaik. Jawaban lain tidak menangani semua kasus. Saya melakukan hal serupa sendiri kecuali saya menggunakan lookahead untuk menangani kasus digit yang hilang: /^[+-]?(?=\di>\.\d)\d*(\.\d*)?$ /
PhilHarvey

1
Itu adalah satu-satunya regex yang benar di sini. Tapi beberapa orang tidak setuju dengan "34.". Saya akan mengusulkan + setelah hari kedua alih-alih *
Gangnus

1
Ini juga cocok dengan 0000.2, yang mungkin bukan yang diinginkan.
Aaron Zorel

11

Coba regex ini:

\d+\.?\d*

\ d + digit sebelum desimal opsional
.? desimal opsional (opsional karena? pembilang)
\ d * digit opsional setelah desimal


1
Tidak, yang itu tidak cocok 123.
Bart Kiers

1
Terima kasih atas catatannya. Mengubah regex saya.
Kash

4
Memang, tapi sekarang Anda baru saja mengeditnya menjadi apa yang sudah diposting oleh orang lain. Pertimbangkan hanya menghapus jawaban "benar" lainnya.
Bart Kiers

10

Saya pikir ini yang terbaik karena sesuai dengan semua persyaratan:

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

1
Bagi saya ini adalah jawaban terbaik, karena string: "4." (misalnya) bukan angka yang valid setidaknya dalam bahasa ruby. Namun, jawaban yang paling disukai menerima "4." sebagai angka regex, yang salah.
Victor

3

Saya akhirnya menggunakan yang berikut:

^\d*\.?\d+$

Ini membuat hal-hal berikut tidak valid:

.
3.

Anda mungkin perlu garis miring tergantung pada bahasa yang Anda gunakan. Misalnya: /^\d*\.?\d+$/
Charles Naccio

ini akan memungkinkan.3
Royi Namir

3

Anda dapat menggunakan ini:

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

pertandingan:
11
11.1
0.2

tidak cocok:
.2
2.
2.6.9


Terima kasih, sangat sederhana dan sesuai dengan yang saya butuhkan
Hany

2

Bahasa apa? Dalam gaya Perl:^\d+(\.\d*)?$


2

Inilah yang saya lakukan. Ini lebih ketat dari yang manapun di atas (dan lebih benar dari beberapa):

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

String yang lolos:

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

String yang gagal:

.
00000
01
.0.
..
00.123
02.134

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

harus mencerminkan apa yang biasanya orang anggap sebagai bilangan desimal yang dibentuk dengan baik.

Digit sebelum koma desimal dapat berupa satu digit, dalam hal ini bisa dari 0 hingga 9, atau lebih dari satu digit, dalam hal ini tidak boleh dimulai dengan 0.

Jika ada angka sebelum tanda desimal, maka desimal dan angka setelahnya adalah opsional. Jika tidak, desimal harus ada diikuti oleh setidaknya satu digit. Perhatikan bahwa beberapa tanda 0 diperbolehkan setelah titik desimal.

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

cocok dengan yang berikut ini:

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

serta padanan bertanda tangan mereka, sedangkan menolak hal-hal berikut:

.
00
01
00.0
01.3

dan padanannya yang bertanda, serta string kosong.


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

bersih dan sederhana.

Ini menggunakan Suffix dan Prefix, fitur RegEx.

Ini secara langsung mengembalikan true - false untuk kondisi IsMatch


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

Datang dengan ini. Mengizinkan bilangan bulat dan desimal, tetapi memaksa desimal lengkap (angka di depan dan di belakang) jika Anda memutuskan untuk memasukkan desimal.


1

Apa yang Anda tanyakan sudah dijawab jadi ini hanya info tambahan bagi mereka yang hanya menginginkan 2 digit desimal jika titik desimal opsional dimasukkan:

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

^: awal string
\ d: digit (sama dengan [0-9])
+: satu dan waktu tak terbatas

Menangkap Grup (. \ D {2})?
? : nol dan satu kali. : karakter.
\ d: digit (sama dengan [0-9])
{2}: tepat 2 kali
$: akhir string

1: pertandingan
123: pertandingan
123.00: pertandingan 123
.: tidak ada pertandingan
123 ..: tidak ada pertandingan
123.0: tidak ada pertandingan
123.000: tidak ada pertandingan
123.00.00: tidak ada pertandingan


Apakah ini cocok dengan angka negatif?
Alexander Ryan Baggett

1
@AlexanderRyanBaggett Anda perlu memeriksa tanda negatif sehingga akan menjadi: ^ -? \ D + (\. \ D {2})? $
PersyJack

0

Di Perl, gunakan Regexp :: Common yang memungkinkan Anda menyusun ekspresi reguler yang disetel dengan tepat untuk format bilangan tertentu. Jika Anda tidak menggunakan Perl, ekspresi reguler yang dihasilkan biasanya masih dapat digunakan oleh bahasa lain.

Mencetak hasil dari menghasilkan contoh ekspresi reguler di 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]+))|))

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.