2008-10-27 38 views
29

Tôi đang phát triển một thuật toán để phân tích cú pháp một số trong chuỗi chuỗi ngắn. Các chuỗi này có phần thường xuyên, nhưng có một vài dạng chung khác nhau và một số ngoại lệ. Tôi đang cố gắng xây dựng một tập hợp các regex sẽ xử lý các biểu mẫu và ngoại lệ khác nhau; Tôi sẽ áp dụng chúng cái khác để xem nếu tôi có một trận đấu.Kết hợp một chuỗi con tùy chọn trong một regex

Một trong những hình thức đi một cái gì đó như thế này:

X (Y) Z 

đâu:

  • X là một số tôi muốn chụp.
  • Z là văn bản tĩnh, được xác định trước. về cơ bản là cách tôi xác định xem biểu mẫu cụ thể này có thể áp dụng được hay không.
  • Y là một chuỗi có chiều dài và nội dung không xác định, được bao quanh bởi dấu ngoặc đơn.

Ngoài ra: Y là tùy chọn; nó không luôn xuất hiện trong một chuỗi với Z và X. Vì vậy, tôi muốn có thể để trích xuất các số từ tất cả các chuỗi:

  • 10 Z
  • 20 (foo) Z
  • 30 (bar) Z

Ngay bây giờ, tôi có một regex mà sẽ nắm bắt được một đầu tiên:

([0-9]+) +Z 

vấn đề của tôi là tôi không biết làm thế nào để xây dựng một regex sẽ khớp với một chuỗi ký tự nếu và chỉ khi chúng được đặt trong dấu ngoặc đơn. Điều này có thể được thực hiện trong một regex không?

Trả lời

46
(\d+)\s+(\(.*?\))?\s?Z 

Ghi chú dấu ngoặc đơn thoát và dấu? (số không hoặc một lần) định lượng. Bất kỳ nhóm nào bạn không muốn chụp có thể là (?: Nhóm không chụp).

Tôi đồng ý về khoảng trắng. \ s là một lựa chọn tốt hơn ở đó. Tôi cũng đã thay đổi định lượng để đảm bảo có các chữ số ở đầu. Theo như các dòng mới, điều đó sẽ phụ thuộc vào ngữ cảnh: nếu tệp được phân tích cú pháp từng dòng thì nó sẽ không là vấn đề. Một tùy chọn khác là để neo bắt đầu và kết thúc của dòng (thêm^ở phía trước và $ ở cuối).

+0

Các khoảng trống là tĩnh. Thay thế chúng bằng \ s + –

+0

hoặc đặt một trong số chúng bên trong()? –

+0

Lưu ý rằng nếu regex chụp \ n bằng. hoặc nếu có nhiều phiên bản trên một dòng, điều này sẽ không tham lam: (\ d *) (\ (. *? \))? Z – eyelidlessness

2

Hãy thử điều này:

X (\(Y\))? Z 
7

Bạn có thể làm điều này:

([0-9]+) (\([^)]+\))? Z 

này sẽ không làm việc với dấu ngoặc lồng nhau cho Y, tuy nhiên. Làm tổ đòi hỏi đệ quy mà không phải là hoàn toàn thường xuyên nữa (nhưng không có bối cảnh). Động cơ regexp hiện đại vẫn có thể xử lý nó, mặc dù với một số khó khăn (back-references).

+1

May mắn thay tôi không nghĩ rằng tôi cần phải xử lý parens lồng nhau. –

14

này nên làm việc:

^\d+\s?(\([^\)]+\)\s?)?Z$ 

đã không kiểm tra nó mặc dù, nhưng hãy để tôi cung cấp cho bạn sự phân hủy, vì vậy nếu có bất kỳ lỗi trái họ nên được khá đơn giản để tìm thấy:

đầu tiên phần đầu:

^ = beginning of string 
\d+ = one or more decimal characters 
\s? = one optional whitespace 

Sau đó, phần này:

(\([^\)]+\)\s?)? 

là thực sự:

(.............)? 

Mà làm cho các nội dung sau không bắt buộc, chỉ khi nó tồn tại đầy đủ

\([^\)]+\)\s? 

\(= an opening bracket 
[^\)]+ = a series of at least one character that is not a closing bracket 
\) = followed by a closing bracket 
\s? = followed by one optional whitespace 

Và cuối cùng được tạo thành từ

Z$ 

đâu

Z = your constant string 
$ = the end of the string 
Các vấn đề liên quan