Biểu thức chính quy số thập phân, trong đó chữ số sau số thập phân là tùy chọn


112

Tôi cần một biểu thức chính quy xác thực một số, nhưng không yêu cầu một chữ số sau số thập phân. I E.

123
123.
123.4

tất cả sẽ hợp lệ

123..

sẽ không hợp lệ

Bất kỳ sẽ được đánh giá rất cao!


Câu trả lời tốt nhất là ở đây: stackoverflow.com/a/39399503/715269
Gangnus

Câu trả lời:


189

Sử dụng như sau:

/^\d*\.?\d*$/
  • ^ - Đầu dòng;
  • \d* - 0 hoặc nhiều chữ số;
  • \.?- Một dấu chấm tùy chọn (thoát ra, vì trong regex, .là một ký tự đặc biệt);
  • \d* - 0 hoặc nhiều chữ số (phần thập phân);
  • $ - Cuối dòng.

Điều này cho phép 0,5 thập phân thay vì yêu cầu số 0 ở đầu, chẳng hạn như 0,5


2
@OrangeDog, kết quả phù hợp ban đầu của bạn nhiều hơn mong muốn. ví dụ: 'cow3.45tornado';)
S. Albano

39
Nó cũng khớp với một dấu chấm không phải là số thập phân hợp lệ. Một regex tốt hơn /^\d*\.?\d+$/sẽ buộc một chữ số sau dấu thập phân.
Chandranshu

2
@Chandranshu và nó khớp với một chuỗi trống, mà thay đổi của bạn cũng sẽ giải quyết được.
OGHaza

2
@Chandranshu "không đòi hỏi một chữ số sau chữ số thập phân"
OrangeDog

3
Giải pháp này không hoạt động. Nó yêu cầu số thập phân trong khi OP nói rõ ràng: số thập phân tùy chọn.
Alex G

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

Một hoặc nhiều chữ số ( \d+), dấu chấm tùy chọn ( \.?), không hoặc nhiều chữ số ( \d*).

Tùy thuộc vào cách sử dụng của bạn hoặc công cụ regex, bạn có thể cần thêm neo dòng bắt đầu / kết thúc:

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

Hình ảnh hóa biểu thức chính quy

Bản trình diễn gỡ lỗi


12
Vâng, nhưng câu trả lời được bình chọn hàng đầu là sai, nó khớp với cả hai .và chuỗi trống.
OrangeDog

1
@Gangnus Cũng không nói rằng ".digit" phải được khớp. Nếu họ muốn điều đó, thì họ nên nói.
OrangeDog

2
@EqualityInTech Tôi khá chắc chắn là không - nó không có nhóm nào cả.
OrangeDog

1
Hmm ... Tôi nghĩ rằng tôi có thể không hiểu đầy đủ về ma quỷ như tôi đã nghĩ. Lấy làm tiếc.
JDB vẫn nhớ Monica

1
@AlexanderRyanBaggett này khớp chính xác với những gì câu hỏi đã chỉ định. Như bạn có thể thấy, nó hoàn toàn không bao gồm -.
OrangeDog

74

Bạn cần một biểu thức chính quy như sau để thực hiện đúng cách:

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

Cùng một biểu thức với khoảng trắng, sử dụng công cụ sửa đổi mở rộng (như được Perl hỗ trợ):

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

hoặc với nhận xét:

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

Ví dụ, nó sẽ khớp với:

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

Và sẽ từ chối những không phải số này:

  • . (dấu thập phân duy nhất)
  • -. (dấu thập phân âm)
  • +. (cộng với dấu thập phân)
  • (chuỗi trống)

Các giải pháp đơn giản hơn có thể từ chối sai các số hợp lệ hoặc khớp với các số không phải là số này.


1
Tốt nhất vì nó khớp với một số theo sau là dấu chấm (42.). Tuy nhiên, có một lỗi / dương tính giả vì nó khớp với điều này: 3 .... 3 có thể được sửa bằng cách thêm hai dấu ngoặc đơn để thực thi ^ $ ký tự đầu và cuối: / ^ ([+ -]? (\ D + (\ . \ d *)?) | (\. \ d +)) $ /
Pete Alvin

1
Cảm ơn Pete, rất tốt. Câu trả lời hiện đã được sửa chữa, bằng cách thêm dấu ngoặc đơn để nó hoạt động như dự định. Nó bây giờ được viết như thế nào ^A?(B|C)$. Trước đây, nó được viết như thế ^A?B|C$thực sự có nghĩa (^A?B)|(C$)là không chính xác. Lưu ý: ^(A?B|C)$cũng không chính xác, vì nó thực sự có nghĩa là ^((A?B)|(C))$không khớp với "+.5".
Hoylen

2
Đây là câu trả lời tốt nhất. Các câu trả lời khác không xử lý được tất cả các trường hợp. Tôi tự làm một việc tương tự ngoại trừ việc tôi sử dụng lookahead để xử lý các trường hợp thiếu chữ số: /^[+-]?(?=\d|\.\d)\d*(\.\d*)?$ /
PhilHarvey

1
Đó là regex chính xác duy nhất ở đây. Nhưng một số người sẽ không đồng ý với "34". Tôi sẽ đề xuất + sau khi d giây thay vì *
Gangnus

1
Điều này cũng khớp với 0000.2, có thể không phải là những gì mong muốn.
Aaron Zorel

11

Hãy thử regex này:

\d+\.?\d*

\ d + chữ số trước số thập phân tùy chọn
.? số thập phân tùy chọn (tùy chọn do bộ định lượng?)
\ d * chữ số tùy chọn sau số thập phân


1
Không, đó là một không phù hợp123.
Bart Kiers

1
Cảm ơn đã lưu ý. Đã sửa đổi regex của tôi.
Kash

4
Thật vậy, nhưng bây giờ bạn chỉ chỉnh sửa nó thành những gì đã được đăng bởi người khác. Hãy xem xét chỉ cần loại bỏ thêm một câu trả lời "đúng".
Bart Kiers

10

Tôi nghĩ đây là cái tốt nhất vì nó phù hợp với tất cả các yêu cầu:

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

1
Đối với tôi, đây là câu trả lời tốt nhất, vì chuỗi: "4." (ví dụ) không phải là một số hợp lệ ít nhất bằng ngôn ngữ ruby. Tuy nhiên, các câu trả lời được ủng hộ nhiều nhất chấp nhận "4." như một số regex, điều này là sai.
Victor

3

Tôi đã kết thúc bằng cách sử dụng như sau:

^\d*\.?\d+$

Điều này làm cho thông tin sau không hợp lệ:

.
3.

Bạn có thể cần dấu gạch chéo tùy thuộc vào ngôn ngữ bạn đang sử dụng. Ví dụ: /^\d*\.?\d+$/
Charles Naccio

điều này sẽ cho phép.3
Royi Namir

3

bạn có thể sử dụng cái này:

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

trận đấu:
11
11,1
0,2

không khớp:
.2
2.
2.6.9


Cảm ơn, rất đơn giản và phù hợp những gì tôi cần
Hany

2

Ngôn ngữ nào? Theo kiểu Perl:^\d+(\.\d*)?$


2

Đây là những gì tôi đã làm. Nó nghiêm ngặt hơn bất kỳ điều nào ở trên (và đúng hơn một số điều):

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

Chuỗi đi qua:

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

Chuỗi không thành công:

.
00000
01
.0.
..
00.123
02.134

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

nên phản ánh những gì mọi người thường nghĩ về một số thập phân được hình thành tốt.

Các chữ số trước dấu thập phân có thể là một chữ số duy nhất, trong trường hợp này, nó có thể từ 0 đến 9 hoặc nhiều hơn một chữ số, trong trường hợp đó, nó không thể bắt đầu bằng số 0.

Nếu có bất kỳ chữ số nào đứng trước dấu thập phân, thì phần thập phân và các chữ số theo sau nó là tùy chọn. Nếu không, phải có một số thập phân theo sau là ít nhất một chữ số. Lưu ý rằng cho phép nhiều số 0 ở cuối sau dấu thập phân.

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

khớp chính xác với những điều sau:

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

cũng như các điểm tương đương đã ký của chúng, trong khi nó từ chối những điều sau:

.
00
01
00.0
01.3

và các dấu tương đương của chúng, cũng như chuỗi trống.


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

sạch sẽ và đơn giản.

Điều này sử dụng các tính năng Hậu tố và Tiền tố, RegEx.

Nó trực tiếp trả về true - false cho điều kiện IsMatch


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

Nghĩ ra cái này. Cho phép cả số nguyên và số thập phân, nhưng buộc phải nhập một số thập phân hoàn chỉnh (số đứng đầu và ở cuối) nếu bạn quyết định nhập số thập phân.


1

Những gì bạn hỏi đã được trả lời nên đây chỉ là thông tin bổ sung cho những người chỉ muốn có 2 chữ số thập phân nếu nhập dấu thập phân tùy chọn:

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

^: bắt đầu của chuỗi
\ d: một chữ số (bằng [0-9])
+: một và không giới hạn số lần

Chụp nhóm (. \ D {2})?
? : không và một lần. : tính cách .
\ d: một chữ số (bằng [0-9])
{2}: đúng 2 lần
$: end of string

1: khớp
123: khớp
123,00: khớp
123.: không khớp
123 ..: không khớp
123,0
: không khớp
123,000: không khớp 123,00.00: không khớp


Điều này có khớp với số âm không?
Alexander Ryan Baggett

1
@AlexanderRyanBaggett bạn cần kiểm tra dấu âm nên nó sẽ là: ^ -? \ D + (\. \ D {2})? $
PersyJack

0

Trong Perl, sử dụng Regexp :: Common sẽ cho phép bạn tập hợp một biểu thức chính quy được tinh chỉnh cho định dạng số cụ thể của bạn. Nếu bạn không sử dụng Perl, biểu thức chính quy đã tạo vẫn có thể được sử dụng bởi các ngôn ngữ khác.

In kết quả của việc tạo biểu thức chính quy mẫu trong 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]+))|))

0

thử cái này. ^[0-9]\d{0,9}(\.\d{1,3})?%?$nó được thử nghiệm và làm việc cho tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.