tags:

views:

407

answers:

3

In PHP I can use a foreach loop such that I have access to both the key and value for example:

foreach($array as $key => $value)

I have the following code:

Regex regex = new Regex(pattern);
MatchCollection mc = regex.Matches(haystack);
for (int i = 0; i < mc.Count; i++)
{
     GroupCollection gc = mc[i].Groups;
     Dictionary<string, string> match = new Dictionary<string, string>();
     for (int j = 0; j < gc.Count; j++)
     {
        //here
     }
     this.matches.Add(i, match);
}

at //here I'd like to match.add(key, value) but I cannot figure out how to get the key from the GroupCollection, which in this case should be the name of the capturing group. I know that gc["goupName"].Value contains the value of the match.

+3  A: 

You cannot access the group name directly, hou have to use GroupNameFromNumber on the regex instance (see doc).

Regex regex = new Regex(pattern);
MatchCollection mc = regex.Matches(haystack);
for (int i = 0; i < mc.Count; i++)
{
     GroupCollection gc = mc[i].Groups;
     Dictionary<string, string> match = new Dictionary<string, string>();
     for (int j = 0; j < gc.Count; j++)
     {
        match.Add(regex.GroupNameFromNumber(j), gc[j].Value);
     }
     this.matches.Add(i, match);
}
Obalix
+9  A: 

In .NET, the group names are available against the Regex instance:

// outside all of the loops
string[] groupNames = regex.GetGroupNames();

Then you can iterate based on this:

Dictionary<string, string> match = new Dictionary<string, string>();
foreach(string groupName in groupNames) {
    match.Add(groupName, gc[groupName].Value);
}

Or if you want to use LINQ:

var match = groupNames.ToDictionary(
            groupName => groupName, groupName => gc[groupName].Value);
Marc Gravell
+3  A: 

In C# 3, you can also use LINQ to do this kind of collection processing. Classes for working with regular expressions implement only non-generic IEnumerable, so you need to specify a couple of types, but it's still quite elegant.

The following code gives you a collection of dictionaries that contain the group name as the key and the matched value as a value. It uses Marc's suggestion to use ToDictionary, except that it specifies group name as the key (I think that Marc's code uses matched value as the key and group name as the value).

Regex regex = new Regex(pattern);
var q =
  from Match mci in regex.Matches(haystack)
  select regex.GetGroupNames().ToDictionary(
    name => name, name => mci.Groups[name].Value);

Then you could just assign the result to your this.matches.

Tomas Petricek
@Tomas - fixed that; good spot.
Marc Gravell