2010-12-29 36 views
5
myRegex.GetGroupNames() 

Dường như cũng trả về các nhóm được đánh số ... làm cách nào để tôi chỉ nhận được các nhóm được đặt tên?C# Regex: Nhận tên nhóm?

Một giải pháp sử dụng đối tượng Đối sánh thực tế cũng sẽ ổn.

+0

Tại sao bạn có cả nhóm được đặt tên và đánh số? Tại sao không chỉ dính vào cái này hay cái kia? Bạn có thể đăng biểu thức chính quy của mình không? –

+0

@Mark: Tôi không biết. Chúng được thêm tự động (nhóm có thể được trưng cầu theo tên hoặc số). Regex của tôi là '^ (?:/Image :(? \ d +)) $'. Các dấu ngoặc đơn bên ngoài không được bắt nếu tôi không nhầm. – mpen

+0

** Edit: ** Trên thực tế, 0 có lẽ là một trong những phù hợp với toàn bộ regex ... – mpen

Trả lời

2
public string[] GetGroupNames(Regex re) 
{ 
    var groupNames = re.GetGroupNames(); 
    var groupNumbers = re.GetGroupNumbers(); 

    Contract.Assert(groupNames.Length == groupNumbers.Length); 

    return Enumerable.Range(0, groupNames.Length) 
     .Where(i => groupNames[i] != groupNumbers[i].ToString()) 
     .Select(i => groupNames[i]) 
     .ToArray(); 
} 

Trên thực tế, đây vẫn sẽ thất bại khi tên nhóm và số xảy ra để được như vậy: \ Nhưng nó sẽ thành công ngay cả khi tên nhóm là một con số, miễn là số lượng là không giống nhau làm chỉ mục của nó.

+0

Có ... đọc đoạn cuối. Nó vẫn thất bại dưới một điều kiện đó. Nếu bạn biết cách này, xin hãy khai sáng cho tôi :) ** Edit: ** Doh ... bạn đã xóa bình luận của bạn. Bây giờ điều này trông ra khỏi vị trí. – mpen

+0

Tuyệt vời! Đã tiết kiệm rất nhiều thời gian. Cảm ơn. – Cylian

2

Xem các nhận xét/câu trả lời khác về cách sử dụng (?:) và/hoặc gắn bó với "một kiểu". Đây là cách tiếp cận tốt nhất của tôi để cố gắng giải quyết trực tiếp câu hỏi:

var named = regex.GetGroupNames().Where(x => !Regex.IsMatch(x, "^\\d+$")); 

Tuy nhiên, điều này sẽ không thành công đối với cụm từ thông dụng như (?<42>...).

Mã hóa vui vẻ.

+0

Có ... Tôi nghĩ rằng chúng tôi có thể làm một tốt hơn mặc dù. Mã hóa nó ngay bây giờ. – mpen

+0

@Ralph Hãy xem xét trường hợp này: '(? <1> ..)' - GetGroupNumbers/Names vẫn nên "xếp hàng" :-) –

+0

Yeah :(Nhưng nó vẫn còn mạnh mẽ hơn một chút so với giải pháp này: P – mpen

7

Có sử dụng tùy chọn RegexOptions.ExplicitCapture khi tạo regex làm những gì bạn muốn không? ví dụ.

Regex theRegex = new Regex(@"\b(?<word>\w+)\b", RegexOptions.ExplicitCapture); 

Từ MSDN:

Chỉ định rằng ảnh chụp chỉ có giá trị được đặt tên một cách rõ ràng hoặc đánh số nhóm có dạng (?<name>...). Điều này cho phép dấu ngoặc đơn không được đặt tên hoạt động dưới dạng các nhóm không tuân thủ mà không có sự vụng về cú pháp của biểu thức (?:...).

Vì vậy, bạn sẽ không cần phải lo lắng về việc liệu người dùng API của bạn có thể hoặc không thể sử dụng nhóm không chụp nếu tùy chọn này được đặt.

+0

Ồ lén lút. Tôi muốn xử lý các ảnh được đặt tên và đánh số riêng biệt, đó là lý do tại sao điều quan trọng là tôi phân biệt giữa hai ... nhưng tôi đang tranh luận về sự hỗ trợ của các ảnh chụp được đánh số hữu ích như thế nào. ** Edit: * * Ngay cả khi chụp rõ ràng, nó vẫn trả về lần chụp thứ 0, nhưng điều đó có thể dễ dàng cắt bớt. – mpen

+2

Các nhóm được đặt tên và các nhóm được đánh số không nên được sử dụng trong cùng một regex, nó quá khó hiểu. nguồn của các regexes, bạn có thể tiết kiệm cho mình rất nhiều rắc rối bằng cách buộc chế độ ExplicitCapture, ngoài ra, bạn có thể cấm sử dụng tên nhóm * trông giống như các số, ví dụ '(? <2> ...) ' –

+0

@Alan: Có lẽ chúng không nên trộn lẫn, nhưng tôi nghĩ chúng vẫn nên có lựa chọn. Điều này đang đi vào một url-router cho một khuôn khổ web.Các trận đấu được đặt tên sẽ trở thành đối số cho một hàm có tham số bằng cùng một tên. Ngoài ra, họ có thể sử dụng các trận đấu được đánh số để điền các đối số từ trái sang phải. – mpen

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