2013-08-16 22 views
5

Tôi đã phát triển một regex phù hợp với thông số trang pstops. (Khoảng trống Regex không đáng kể.)Với các nhóm được đặt tên lồng nhau trong một regex, có thể điều hướng phân cấp?

^(?:(?<modulo>\d+):)? 
(?<pages> 
    (?<pagespec> 
    (?<pageno>-?\d+) 
    (?<rotation>[RUL]?)? 
    (?:@(?<scale>\d*(?:\.\d+)))? 
    (?:\(
     (?<xoff>\d*\.?\d+)(?<xunit>in|cm|w|h)? 
     , 
     (?<yoff>\d*\.?\d+)(?<yunit>in|cm|w|h)? 
    \))? 
    \+?)+,? 
)+$ 

.

'Sample string: 
'"4:[email protected](21cm,0)[email protected](21cm,14.85cm),1L(21cm,0)[email protected](21cm,14.85cm)" 

Như bạn có thể thấy, có các nhóm con được đặt tên lồng nhau. Ví dụ: pagespec không cần chỉ định rotation. Tôi muốn để có thể làm gì đó để tác dụng của việc này:

If match.Groups("pages").Captures(0).Groups("pagespecs").Captures(1).Groups("rotation").Value > "" 

nhưng tất nhiên Captures không có tài sản Groups. Có cách nào để truy cập các phân nhóm trong hệ thống phân cấp theo cách này không?

EDIT: Dưới đây là một ví dụ minmal hơn (màu trắng không gian đáng kể thời gian này):

(?<paragraph>(?:(?<sentence>The (?<child>boy|girl) is hungry\.|The (?<parent>mother|father) is angry\.)\s*)+) 

khớp với chuỗi này:

The boy is hungry. The mother is angry. The girl is hungry. 

sản xuất một trận đấu. Trong trận đấu đó,

  • Groups("paragraph") có một lần chụp phù hợp với toàn bộ chuỗi.
  • Groups("sentence") có ba ảnh chụp.
  • Groups("child") có hai ảnh chụp, boygirl.
  • Groups("parent") có một ảnh chụp, mother.

Nhưng không có gì mà nói với tôi rằng việc bắt giữ duy nhất cho parent nằm trong chụp thứ hai cho sentence, trừ khi tôi bắt đầu xem xét IndexLength cho từng chụp được.

EDIT: Dưới đây là câu trả lời cuối cùng:

^(?:(?<modulo>\d+):)? 
(?<pages> 
    (?<pagespec> 
    (?<pageno>-?\d+) 
    (?<rotation>[RUL]?) 
    (?:@(?<scale>\d*(?:\.\d+)))? 
    (?:\(
     (?<xoff>\d*\.?\d+)(?<xunit>in|cm|w|h)? 
     , 
     (?<yoff>\d*\.?\d+)(?<yunit>in|cm|w|h)? 
    \))? 
    (?<pageno>)(?<rotation>)(?<scale>)(?<xoff>)(?<xunit>)(?<yoff>)(?<yunit>) 
    \+?)+,? 
(?<pagespec>) 
)+ 

này đẩy một NULL vào pagespec chồng giữa mỗi page, vì vậy họ có thể tương quan với page; và NULL vào mỗi ngăn xếp có tên khác giữa mỗi pagespec. Gee, phân tích cú pháp rất khó ...

+1

Tôi đoán nó sẽ giúp ích cho câu hỏi nếu bạn giảm điều này xuống một ví dụ tối thiểu. Cái gì đó giống như 'xy @ z' với' (? :(? (? :(? [az]) | -) + | @) + 'có thể làm (như trong, làm cách nào để biết nếu' Nhóm (Captures (1) 'thuộc về' Groups ("part"). Captures (0) 'hoặc' (1) ') Nhưng câu hỏi hay, tôi cũng muốn được quan tâm đến một giải pháp :). –

Trả lời

2

Tôi không nghĩ điều này là có thể. Theo như tôi biết, các nhóm khác nhau không có mối quan hệ với nhau về cách chúng được lồng trong mẫu. Hơn nữa, một hệ thống phân cấp như vậy sẽ thậm chí không có ý nghĩa, bởi vì tên nhóm có thể được tái sử dụng trong .NET:

(?<group> 
    (?<sub>.) 
)+ 
(?<sub>.) 

Tôi đoán nó sẽ là bằng cách nào đó có thể đại diện này một cây phân cấp là tốt, nhưng điều này sẽ đánh bại mục đích của các ngăn xếp, .NET duy trì để chụp. Có lẽ tôi nên làm rõ rằng: .NET không chỉ đơn giản là liệt kê tất cả các ảnh chụp của một nhóm - nó đẩy chúng vào một ngăn xếp mà từ đó chúng có thể được popped một lần nữa với ví dụ (?<-sub>). Bây giờ làm thế nào bạn sẽ đối xử với điều đó, nếu một thể hiện của một nhóm sau đó bật một cái gì đó từ ngăn xếp đã được kết hợp cách trước đó?Tôi nghĩ rằng nó sẽ trở nên rất không rõ ràng nếu không thể giải quyết cho trường hợp chung.

Điều bạn thực sự muốn là nhóm các ảnh chụp pagespecs theo cách chúng tương ứng với một "phiên bản" duy nhất là pages. Bạn có thể làm điều này bằng những lý do rất có thể ngăn chặn các giải pháp, bạn muốn có: bạn có thể tái sử dụng nhóm:

^(?:(?<modulo>\d+):)? 
(?<pages> 
    (?<pagespecs> 
    # here goes your actual pagespec pattern 
    [+]?)+ 
    (?<pagespecs>) 
    ,? 
)+$ 

Bây giờ ở phần cuối của mỗi page bạn đẩy một chuỗi rỗng sang pagespecs stack. Vì một "phiên bản" bình thường của pagespecs sẽ luôn chứa ít nhất một ký tự, bạn biết rằng mọi ảnh chụp trống phải đến từ việc sử dụng riêng biệt pagespecs. Vì vậy, bây giờ bạn có thể chia cho bạn Captures("pagespecs") bởi các phần tử chuỗi rỗng và sau đó chỉ liên kết chúng theo thứ tự với các phần tử trong Captures("pages").

+0

Điều này rất thú vị. Tôi sẽ thử nó. –

+0

Lưu ý rằng một pagepec không cần phải quay. Tôi có thể có một trang, năm trang và chỉ một vòng quay. Làm cách nào để liên kết vòng xoay đó với đúng pagespec? –

+0

OK, xoay là một ví dụ xấu - có vẻ như nó biến thành NULL khi không có mặt. Nhưng xoff/xunit/yoff/yunit nằm trong nhóm chụp không tên mà hoàn toàn không bắt buộc. Bỏ qua đó phá hủy liên kết. –

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