2010-02-19 1 views
12

một biểu thức chính quy tốt để xử lý một số dấu chấm động (ví dụ như phao Java)Làm thế nào để phát hiện một số dấu chấm động sử dụng một biểu thức chính quy

Câu trả lời phải phù hợp với các mục tiêu sau đây là gì:

1) 1. 
2) .2 
3) 3.14 
4) 5e6 
5) 5e-6 
6) 5E+6 
7) 7.e8 
8) 9.0E-10 
9) .11e12 

Nói tóm lại, cần

  • bỏ qua những dấu hiệu trước
  • đòi hỏi ký tự đầu tiên bên trái của dấu thập phân là khác không
  • phép 0 hoặc nhiều chữ số ở hai bên của dấu thập phân
  • cho phép một số mà không có một dấu thập phân
  • phép ký hiệu khoa học
  • phép vốn hay chữ thường 'e'
  • cho phép số mũ dương hoặc âm

Đối với những người đang thắc mắc, có đây là vấn đề về bài tập ở nhà. Chúng tôi nhận được điều này như là một bài tập trong lớp CS tốt nghiệp của tôi về trình biên dịch. Tôi đã trả lời câu trả lời cho lớp và sẽ đăng câu trả lời cho câu hỏi này.

[Epilogue] Giải pháp của tôi không nhận được tín dụng đầy đủ vì nó không xử lý nhiều hơn 1 chữ số ở bên trái của số thập phân. Nhiệm vụ đã đề cập đến việc xử lý các phao Java mặc dù không có ví dụ nào có nhiều hơn 1 chữ số ở bên trái của số thập phân. Tôi sẽ đăng câu trả lời được chấp nhận trong bài đăng của chính nó.

+0

Cá nhân tôi sẽ viết một loạt các bài kiểm tra đơn vị ... –

+0

Đây là những yêu cầu rất lạ. Biểu thức như vậy sẽ không khớp với "0,5". – user763305

Trả lời

7

[Đây là câu trả lời từ các giáo sư]

Xác định:

012.

N = [1-9]
D = 0 | N
E = [eE] [+ -]? D +
L = 0 | (N D *)

số điểm Sau đó nổi có thể được xuất hiện với: (..? (L D * | D +) E)

| (L E)

Cũng có thể chấp nhận sử dụng D + thay vì L và để thêm [+ -] ?.

Lỗi thường gặp là viết D *. D *, nhưng điều này có thể khớp với '.'.

[Chỉnh sửa]
Ai đó hỏi về dấu hiệu dẫn đầu; Tôi nên hỏi anh ta tại sao nó bị loại trừ nhưng không bao giờ có cơ hội. Vì đây là một phần của bài giảng về ngữ pháp, tôi đoán là nó làm cho vấn đề trở nên dễ dàng hơn (không có khả năng) hoặc có một chi tiết nhỏ trong phân tích nơi bạn phân chia tập vấn đề sao cho giá trị dấu chấm động, bất kể dấu, trọng tâm (có thể).

Nếu bạn phân tích cú pháp thông qua một biểu thức, ví dụ:

-5.04e-10 + 3.14159E10

dấu của giá trị dấu phẩy động là một phần của hoạt động được áp dụng cho giá trị chứ không phải thuộc tính của chính số đó. Nói cách khác,

trừ (5.04e-10)
add (3.14159E10)

để tạo thành kết quả của biểu thức. Trong khi tôi chắc chắn các nhà toán học có thể tranh luận về vấn đề này, hãy nhớ điều này là từ một bài giảng về phân tích cú pháp.

+0

Còn về Infinity và NaN thì sao? –

+0

Kể từ khi tập thể dục về phân tích cú pháp một ngôn ngữ, tôi sẽ mạo hiểm rằng ngữ pháp sẽ cần phải xác định các thẻ đại diện cho các khái niệm đó giả sử chúng được cho phép làm đầu vào. –

23

Chỉ cần chắc cả dấu chấm thập phân và phần E-then-mũ tùy chọn:

[1-9][0-9]*\.?[0-9]*([Ee][+-]?[0-9]+)? 

Tôi không thấy lý do tại sao bạn không muốn có một hàng đầu [+-]? để nắm bắt một dấu hiệu tốt quá, nhưng, bất cứ điều gì -)

Sửa:! có thể có trong thực tế không có chữ số bên trái của dấu thập phân (trong trường hợp mà tôi tưởng tượng có phải là dấu thập phân 1+ chữ số sau nó), vì vậy một thanh dọc (thay thế) i s cần thiết rõ ràng:

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

Lưu ý rằng điều này không khớp với bất kỳ biểu mẫu nào '.x' hoặc' 0.x'. –

+4

@ Alex: Anh ấy có thể không muốn chụp biển báo trong trường hợp đó là một phần của biểu thức, như trong "5-2.5". Đó là mong đợi nếu bạn đang tokenizing mọi thứ, như bạn sẽ được khi viết một trình biên dịch. –

+0

@Anon, phải: '0.x' phải bị từ chối theo quy tắc thứ hai. –

2

Đây là những gì tôi đã bật.

(([1-9]+\.[0-9]*)|([1-9]*\.[0-9]+)|([1-9]+))([eE][-+]?[0-9]+)? 

Để làm cho nó dễ dàng hơn để thảo luận, tôi sẽ đặt tên các phần

(([1-9]+ \. [0-9]*) | ([1-9]* \. [0-9]+) | ([1-9]+)) ([eE] [-+]? [0-9]+)?  
-------------------------------------------------------- ----------------------  
         A          B 

A: phù hợp với tất cả mọi thứ lên đến 'e/E'
B: phù hợp với ký hiệu khoa học

Phá vỡ A chúng tôi nhận được ba phần

(([1-9]+ \. [0-9]*) | ([1-9]* \. [0-9]+) | ([1-9]+)) 
    ----------1---------- ---------2---------- ---3---- 

Phần 1: Cho phép 1 o r chữ số khác từ 1-9, thập phân, 0 hoặc nhiều chữ số sau dấu thập phân (đích 1)
Phần 2: Cho phép 0 hoặc nhiều chữ số từ 1-9, thập phân, 1 hoặc nhiều chữ số sau dấu thập phân (mục tiêu 2)
phần 3: Cho phép 1 hoặc nhiều chữ số 1-9 không có chữ số thập phân (xem # 4 trong danh sách mục tiêu)


Breaking xuống B chúng tôi nhận được 4 phần cơ bản

([eE] [-+]? [0-9]+ )? 
    ..--1- --2-- --3--- -4- .. 

phần 1: yêu cầu chữ 'e' trên hoặc chữ thường cho ký pháp khoa học (ví dụ mục tiêu 8 & 9)
Phần 2: cho phép một dấu hiệu tích cực hay tiêu cực tùy chọn cho số mũ (ví dụ như mục tiêu 4, 5, & 6)
Phần 3: cho phép 1 hoặc nhiều chữ số cho số mũ (mục tiêu 8)
Phần 4: cho phép các ký hiệu khoa học là bắt buộc như một nhóm (mục tiêu 3)

+0

Phần đầu tiên (1) của (A) không cho phép' 10.'. – tur1ng

+0

Phần (1) của (A) có lẽ phải là '([1-9] [0-9] * \. [0-9] *)'. Một thay đổi tương tự là cần thiết cho một phần (3). –

+0

@ tur1ng: đúng nhưng đổ lỗi cho đầu vào thử nghiệm! 8-) –

1
'([-+])?\d*(\.)?\d+(([eE]([-+])?)?\d+)?' 

Đó là cụm từ thông dụng tôi đã đến khi cố gắng giải quyết loại tác vụ này trong Matlab. Trên thực tế, nó sẽ không phát hiện đúng các con số như (1.) nhưng một số thay đổi bổ sung có thể giải quyết vấn đề ... tốt, có thể những điều sau đây sẽ khắc phục điều đó:

'([-+])?(\d+(\.)?\d*|\d*(\.)?\d+)(([eE]([-+])?)?\d+)?' 
1

@Kelly S. French: the sign is thiếu bởi vì trong một trình phân tích cú pháp nó sẽ được thêm vào bởi biểu thức trừ (âm) đơn nhất, do đó nó không phải là cần thiết để được phát hiện như là một phần của phao.

1

@Kelly S. French, cụm từ thông dụng này khớp với tất cả các trường hợp kiểm tra của bạn.

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

Nguồn: perldoc perlretut