1
   var matches = Regex.Matches("abcde", "(?:ab(c))(d)").Cast<Match>().ToList();

In this scenario https://regex101.com/ will tell that 'c' and 'd' were matched. But .Net will say that there is a group 'abcd' that has one capture 'abcd'.

How to set .net's regex to ignore non-capturing groups but return the inner group capture. (it would be great to let it be a solution that allows nesting because I create my regex expression recursively from a tree structure of objects).

Thanks.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
jjaskulowski
  • 2,524
  • 3
  • 26
  • 36
  • See this answer http://stackoverflow.com/questions/15170279/regex-with-non-capturing-group-in-c-sharp Or you may find something here http://stackoverflow.com/questions/906493/how-do-i-access-named-capturing-groups-in-a-net-regex – SergeyAn Sep 04 '15 at 02:31
  • Thanks I did checked them, but they are like quite the opposite. These guys are glad when regex captures their groups. My problem is that matches1[0].Captures[0].Value captures the whole "abcd" thing. It should only give me "c" and "d" separately – jjaskulowski Sep 04 '15 at 02:42
  • 1
    The first group (group 0) _always_ refers to the input string. The matched groups start at 1. – Jeff Mercado Sep 04 '15 at 02:46
  • I always use named groups. They are not as easily readable but I don't have to count positions when accessing named captures. Example: ab(?c)d – Christoph Sep 04 '15 at 04:08

1 Answers1

3

The Match object contains Groups and you need to get your captured texts using Match.Groups, not Captures. See MSDN Regex.Match reference:

Because a single match can involve multiple capturing groups, Match has a Groups property that returns the GroupCollection. The Match instance itself is equivalent to the first object in the collection, at Match.Groups[0] (Match.Groups(0) in Visual Basic), which represents the entire match.

Your

var matches = Regex.Matches("abcde", "(?:ab(c))(d)").Cast<Match>().ToList();

fetches this:

enter image description here

You can access your values as follows:

var first_c= matches[0].Groups[1].Value;
var first_d= matches[0].Groups[2].Value;

Using named captures would enable you to access them this way:

var matches = Regex.Matches("abcde", "(?:ab(?<myc>c))(?<myd>d)").Cast<Match>().ToList();
var first_c= matches[0].Groups["myc"].Value;
var first_d= matches[0].Groups["myd"].Value;
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563