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!

Trish
sumber
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

João Silva
sumber
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

OrangeDog
sumber
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.

Hoylen
sumber
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

Kash
sumber
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+)?$
Luca Manzo
sumber
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.
Charles Naccio
sumber
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

Ahmed Abdulkafy
sumber
Terima kasih, sangat sederhana dan sesuai dengan yang saya butuhkan
Hany
2

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

Luis
sumber
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
Xiaohang James Miao
sumber
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.

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

bersih dan sederhana.

Ini menggunakan Suffix dan Prefix, fitur RegEx.

Ini secara langsung mengembalikan true - false untuk kondisi IsMatch

Prashant P
sumber
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.

cvanniekerk.dll
sumber
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

PersyJack
sumber
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]+))|))
pndc
sumber
0

coba ini. ^[0-9]\d{0,9}(\.\d{1,3})?%?$itu diuji dan bekerja untuk saya.

Lawrence Eagles
sumber