2012-05-23 26 views
6

Tôi đang tìm cách đơn giản hóa biểu thức chính quy bao gồm các giá trị (ví dụ: 12345), dấu hiệu quan hệ (<,>, < =,> =) và junctors (&,!). Ví dụ. biểu thức:Đơn giản hóa cụm từ thông dụng phức tạp

>= 12345 & <=99999 & !55555 

phải khớp. Tôi có biểu thức chính quy này:

(^<=|^<= | ^>= | ^>= |^<|^>|^< |^> |^)((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 

Tôi đặc biệt hài lòng với sự lặp lại của < =,> =, <,> ở đầu và cuối của biểu thức. Tôi rất vui khi nhận được gợi ý cách làm cho nó đơn giản hơn, ví dụ: nhìn về phía trước, nhìn lại.

+0

bạn muốn kết quả là gì? –

+0

Vui lòng hiển thị một số kết quả phù hợp và có thể là một số ví dụ không phù hợp. Điều này sẽ giúp chúng tôi hiểu những gì bạn đang tìm kiếm để làm. – kevlar1818

+0

Nếu một biểu thức có thể có chiều dài tùy ý, thì bạn có thể muốn thực hiện một vài điều thực hành nhiều hơn các biểu thức thông thường, nếu không nó sẽ trở nên khá xấu và khó đọc. – kevin628

Trả lời

0

Bạn có thể tạo tất cả các khoảng trống tùy chọn (có dấu hỏi) để bạn không phải liệt kê rõ ràng tất cả các khả năng. Ngoài ra, bạn có thể nhóm các biểu tượng bình đẳng/bất bình đẳng trong một bộ ký tự ([]).

Như thế này, tôi nghĩ rằng

(^[<>]=?\s?)((!|)([0-9]{1,5}))(\s?&\s?[<>]=?\s|$)* 
+0

Điều này sẽ khớp với '=', chưa kể '> = <', '>>', '==>', v.v. – kevlar1818

+0

@ kevlar1818: Đúng, nhưng có phải là những khả năng xảy ra không? [<>] =? thực sự là tốt hơn mặc dù, chỉnh sửa. – Junuxx

+0

Từ chối sự xuất hiện của các mẫu (tuy nhiên mẫu không thể xảy ra) không phải là một nghi thức regex tốt. – kevlar1818

0

Làm thế nào về

[<>]=?|\d{1,5}|[&!\|]

Đó sẽ chăm sóc của bạn> /> =/</< = lặp lại. Dường như làm việc cho tôi.

Hãy cho tôi biết nếu điều này trả lời câu hỏi của bạn hoặc cần làm việc.

+0

Đẹp nhất @ kevlar1818. Nhưng nó cũng không bắt được "> = <= 12345 & <= 99999 &! 55555". Chúng ta có muốn bắt những loại ví dụ đó không? – Zecas

+0

Tôi đề xuất nâng cao câu trả lời của bạn với '(([<>] =? |!) \ S * \ d {1,5} \ s *) (& \ s + ([<>] =? |!) \ S * \ d {1,5} \ s *) * '. Bạn nghĩ gì về @ kevlar1818? – Zecas

0

Tôi có quy trình hai bước. Đầu tiên phá vỡ bởi junctor, sau đó kiểm tra các bộ phận riêng lẻ.

final String expr = ">= 12345 & <=99999 & !55555".replaceAll("\\s+", ""); 
for (String s : expr.split("[|&]")) 
    if (!s.matches("([<>]=?|=|!)?\\d+")) { System.out.println("Invalid"); return; } 
System.out.println("Valid"); 

Nhưng chúng tôi vẫn còn đang đoán xem bạn đang nói về xác thực hay cái gì khác.

0

bạn dường như đang chi tiêu rất nhiều nỗ lực phù hợp với không gian tùy chọn. một cái gì đó như \s? (0 - 1) hoặc \s* (0 - nhiều) sẽ tốt hơn.

Ngoài ra, các mục lặp lại được phân cách bởi một cái gì đó luôn khó khăn. tốt nhất là tạo một regexp cho "điều" để đơn giản hóa sự lặp lại.

limit = '\s*([<>]=?|!)\s*\d{1,5}\s*' 
one_or_more = '^' + limit + '(&' + limit + ')*$' 

hay, mở rộng ra:

^\s*([<>]=?|!)\s*\d{1,5}\s*(&\s*([<>]=?|!)\s*\d{1,5}\s*)*$ 

cũng có, ! là một "dấu hiệu liên quan" và không phải là một "junctor" nếu tôi đang tìm hiểu một cách chính xác.

(đối với những người ủng hộ sử dụng một "thực" phân tích cú pháp, ở trên - cấu trúc của one_or_more - có lẽ là làm thế nào bạn sẽ kết thúc thực hiện & danh sách -separated; không có nhu cầu về một phân tích cú pháp nếu bạn chỉ có thể sử dụng chuỗi nối bằng ngôn ngữ).

0

Đây là những gì bạn muốn:

^(\s*([<>]=?)?\s*!?\d{1,5}\s*(&|$))* 

Những giải thích về số tiền phụ biểu thức này sẽ giúp bạn hiểu được toàn bộ sự việc:

\s*: 0 hoặc không gian hơn
([<>]=?)?: Một < hoặc > dấu tùy ý theo sau là =, tất cả tùy chọn
!?: Và tùy chọn !
\d{1,5}: 1-5 chữ số
(&|$): Hoặc là một & hoặc cuối của chuỗi

1

Bắt đầu từ regex của bạn, bạn có thể làm đơn giản hóa này bước sau:

(^<=|^<= | ^>= | ^>= |^<|^>|^< |^> |^)((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
  1. Di chuyển neo trong số thay thế

    ^(<=|<= |>= |>= |<|>|< |> |)((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    

    Tại sao lại có được khoảng trắng trước khi neo? (Loại bỏ đó)

  2. Di chuyển khoảng trắng sau bên ngoài và làm cho nó bắt buộc

    ^(<=|<=|>=|>=|<|>|<|>|) ?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  3. Hủy bỏ các bản sao trong alternations

    ^(<=|>=|<|>|) ?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  4. Việc thay thế trống ở cuối sẽ phù hợp với sản phẩm nào string ==> thay đổi này là tùy chọn

    ^((<=|>=|<|>)? ?)?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  5. Tận dụng dấu bằng tùy chọn và loại bỏ các bản sao

    ^((<|>)=? ?)?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  6. Các thay đổi luân phiên với các nhân vật duy nhất có thể được thay thế bằng một lớp nhân vật

    ^([<>]=? ?)?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  7. làm những điều tương tự với những thay đổi luân phiên ở cuối và bạn kết thúc với một cái gì đó như thế này:

    ^([<>]=? ?)?((!|)([0-9]{1,5}))(?(& ?([<>]=?)?)?|$) 
    

Điều này chưa được kiểm tra, tôi không thay đổi ngữ nghĩa (tôi nghĩ vậy), nhưng tôi đã làm điều này ngay tại đây trong trình soạn thảo.

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