2009-08-06 18 views
6

Tôi đang cố gắng để tạo ra một regex mà sẽ chấp nhận các giá trị sau:Một regex mà sẽ phân tích 00.00

  • (trống)
  • 00,0
  • 00,00

Tôi đã đưa ra ([0-9]){0,2}\.([0-9]){0,2} mà với tôi nói "các chữ số 0 đến 9 xảy ra 0 đến 2 lần, theo sau là '.' ký tự (nên là tùy chọn), theo sau là các chữ số từ 0 đến 9 xảy ra từ 0 đến 2 lần. Nếu chỉ có 2 chữ số được nhập vào '.' là không cần thiết Có gì sai với regex này

+0

Làm thế nào là nó không? Ngoài thực tế là '.' không phải là tùy chọn, như Joachim chỉ ra, tất cả những gì tôi thấy là nó quá dễ dãi (ví dụ: nó cho phép 00. và .00). Ngoài ra, bạn đang sử dụng ngôn ngữ nào? – Beta

Trả lời

15

Bạn đã không làm cho các dấu chấm tùy chọn:.?.

[0-9]{0,2}(\.[0-9]{1,2})? 
+0

Hoàn hảo! Cảm ơn bạn. –

+0

Điều đó cũng khớp với '.0'. Có được không? Nếu không, bạn nên thay đổi phần đầu tiên thành '[0-9] {1,2}'. Điều đó sẽ lần lượt gây ra (trống) để thất bại. Bạn có thể giải quyết vấn đề đó bằng cách gói toàn bộ thứ trong (...)? nhưng nó có thể có ý nghĩa hơn để kiểm tra (trống) một cách riêng biệt. –

+3

Một báo trước: Regex này sẽ khớp với bất kỳ thứ gì vì tất cả các phần đều là tùy chọn. Nếu bạn yêu cầu nó khớp với "a", nó sẽ thành công vì nó khớp với không gian trống "trước khi a". Có lẽ bạn nên neo regex với^và $ (vì bạn muốn khớp một chuỗi rỗng). –

3

Trước hết, {0-2} nên {0,2} như trong trường hợp đầu tiên

Thứ hai Bạn cần nhóm các phần lặp lại

Thứ ba, bạn cần làm toàn bộ phần cuối cùng tùy chọn. Vì nếu có dấu chấm, phải có thứ gì đó sau đó, bạn cũng nên thay đổi điều lặp lại thứ hai thành {1,2}.

([0-9]{0,2})(\.([0-9]{1,2}))? 
2

Có một vài vấn đề với regex của bạn:

  1. Dấu chấm là một nhân vật đặc biệt, và hoạt động như một ký tự đại diện; nếu bạn muốn một dấu chấm, bạn cần phải thoát khỏi nó (\.).
  2. Ngay cả khi bạn thay thế dấu chấm để không phải là ký tự đại diện, thì regex của bạn sẽ khớp với các chuỗi như "0." bởi vì bạn không nói với công cụ biểu thức chính quy để chỉ khớp với dấu chấm nếu có các số sau nó.
  3. Vì biểu thức của bạn không phải là anchored, nó có thể khớp với các chuỗi chứa mẫu trong một từ khác, ví dụ (ví dụ: ab12 sẽ khớp).

Một mô hình tốt hơn sẽ là một cái gì đó như:

/\b[0-9]{0,2}(?:\.[0-9]{1,2})?\b/ 

Lưu ý rằng (?:...) khiến nhóm không tạo ra một backreference, mà có lẽ là không cần thiết trong trường hợp của bạn.

1

Dưới đây là một cách được minh họa trong Perl, để đối sánh chỉ các chuỗi bạn đã liệt kê. Phần quan trọng là phương pháp của nó cho phù hợp với chuỗi rỗng: nó không làm cho mọi yếu tố mẫu tùy chọn, một chiến lược có tác dụng không mong muốn của khớp với hầu hết mọi chuỗi.

use warnings; 
use strict; 

my @data = (
    '', 
    '0', 
    '00', 
    '00.0', 
    '00.00', 
    'foo', # Should not match. 
    '.0',  # Should not match. 
); 

for (@data){ 
    print $_, "\n" if /^$|^[0-9]{1,2}(\.[0-9]{1,2})?$/; 
} 
0

Hầu hết các ví dụ trên không neo đầu ^ và kết thúc $ của dữ liệu.

tôi sẽ giải quyết nó với một trong các cách sau:

  • ^[[:digit:]]{0,2}([.][[:digit:]]{1,2})$
  • ^\d{0,2}([.]\d{1,2})$
  • ^[0-9]{0,2}([.][0-9]{1,2})$

Đối với khả năng đọc, tôi thường thích sử dụng [.]-\. và sử dụng các lớp học POSIX như [[:digit:]].

Các vấn đề liên quan