2015-05-04 16 views
5

Hãy nói rằng tôi có regex sau:Nhận đặt tên subpattern nhóm từ đối tượng .NET regex

var r = new Regex("Space(?<entry>[0-9]{1,3})"); 

Sau đó, tôi có chuỗi:

"Space123" 

Đây là chương trình của tôi:

void Main() 
{ 
    Regex r = new Regex("Space(?<entry>[0-9]{1,3})", RegexOptions.ExplicitCapture); 
    foreach (Match m in r.Matches("Space123")){ 
     m.Groups["entry"].Dump(); //Dump() is linqpad to echo the object to console 
    } 
} 

Điều tôi muốn biết là có cách nào để có được phần biểu thức chính quy khớp với không? Trong trường hợp này:

(?<entry>[0-9]{1,3}) 

Tôi không thể tìm thấy nó ở bất kỳ đâu trong đối tượng, nhưng người ta cho rằng nó có thể truy cập được.

+0

Tôi không chắc chắn về câu hỏi của bạn ... biểu thức chính quy phù hợp là mẫu bạn đã sử dụng 'Không gian (? [0-9] {1,3}) '. Có phải đó là những gì bạn cần? –

+0

Phải, nhưng tôi muốn lấy nó ra khỏi đối tượng, chỉ là phần chụp, cụ thể là ( [0-9] {1,3}), không phải toàn bộ chuỗi. – Matt

+0

Theo như tôi biết, các biểu thức chính quy thường được thực hiện bằng cách xây dựng một máy trạng thái phía sau cảnh phân tích cú pháp và đưa ra một kết quả boolean. Do đó, một biểu thức chính quy duy nhất về cơ bản là hệ thống khép kín của chính nó. Cách duy nhất tôi có thể thấy để làm những gì bạn muốn là tạo ra nhiều biểu thức chính quy nhỏ hơn và kết hợp tất cả chúng với văn bản của bạn một cách riêng biệt. – cmcquillan

Trả lời

5

Bạn có thể tận dụng phương pháp Regex.ToString() lưu trữ mẫu biểu thức chính quy. Các nhóm có tên và các chỉ số tương ứng có thể thu được bằng cách sử dụng Regex.GetGroupNames()Regex.GetGroupNumbers().

Ngoài ra, chúng ta cần một mảng/danh sách các nhóm chụp bên trong mẫu regex, đó là lý do tại sao tôi thêm rxPairedRoundBrackets regex để nắm bắt tất cả văn bản bên trong dấu ngoặc tròn không thoát.

Tôi đề nghị mã này để có được những subpattern regex cho một cụ thể tên nhóm (chỉnh sửa: bây giờ, thậm chí xử lý nhóm ngoặc unescaped lồng nhau!):

var rxPairedRoundBrackets = new Regex(@"(?sx)(?=((?<=[^\\]|^)\(
     (?> 
      (?! (?<!\\)\(| (?<!\\)\)) . 
      | 
      (?<!\\)\((?<Depth>) 
      | 
      (?<!\\)\) (?<-Depth>) 
     )* 
     (?(Depth)(?!)) 
     (?<!\\)\)))+"); 
var r = new Regex(@"(?<OuterSpace>Spa(?<ce>ce))(?<entry>\([0-9]{1,3}\))", RegexOptions.ExplicitCapture); 
var bracketedGrps = rxPairedRoundBrackets.Matches(r.ToString()).Cast<Match>().Select(p => p.Groups[1].Value); 
var GroupDict = r.GetGroupNames().Zip(r.GetGroupNumbers(), (s, i) => new { s, i }) 
           .ToDictionary(item => item.s, item => item.i); 
foreach (Match m in r.Matches("My New Space(123)")) 
{ 
    var id = "entry"; 
    var grp = m.Groups[id]; // Just to see the group value 
    var groupThatMatched = bracketedGrps.ElementAt(GroupDict[id] - 1); 
} 

Và đây là mã cho bạn trường hợp:

r = new Regex("Space(?<entry>[0-9]{1,3})", RegexOptions.ExplicitCapture); 
bracketedGrps = rxPairedRoundBrackets.Matches(r.ToString()).Cast<Match>().Select(p => p.Groups[1].Value); 
GroupDict = r.GetGroupNames().Zip(r.GetGroupNumbers(), (s, i) => new { s, i }) 
          .ToDictionary(item => item.s, item => item.i); 
foreach (Match m in r.Matches("Space123")) 
{ 
    var id = "entry"; 
    var grp = m.Groups[id]; 
    var groupThatMatched = bracketedGrps.ElementAt(GroupDict[id] - 1); 
} 

Output:

enter image description here

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