4

Maybe It's because I'm totally fried right now, but this code:

static void Main(string[] args)
    {
        Regex regx = new Regex(@"^.*(vdi([0-9]+\.[0-9]+)\.exe).*$");
        MatchCollection results = regx.Matches("vdi1.0.exe");
        Console.WriteLine(results.Count);

        if (results.Count > 0)
        {
            foreach (Match r in results)
            {
                Console.WriteLine(r.ToString());
            }
        }
    }

ought to produce the output:

2
vdi1.0.exe
1.0

if I'm not crazy. Instead, it's just producing:

1
vdi1.0.exe

What am I missing?

7
  • 4
    I think you have to use the Groups property to access the subgroups. Commented Jul 16, 2013 at 21:59
  • Mike is correct. You're confusing matches with groups. Commented Jul 16, 2013 at 22:00
  • As a side point, how would the Regex ever group 1.1? That doesn't event occur in vdi1.0.exe. Did you mean 1.0? Commented Jul 16, 2013 at 22:01
  • @voithos yeah, I did. oops. Commented Jul 16, 2013 at 22:03
  • @MikeChristensen right - I forgot about that. Am I the only one that doesn't find that intuitive at all? Commented Jul 16, 2013 at 22:04

1 Answer 1

8

Your Regular Expression will only return one Match object with 2 subgroups. You can access those groups using the Groups collection of the Match object.

Try something like:

foreach (Match r in results) // In your case, there will only be 1 match here
{
   foreach(Group group in r.Groups) // Loop through the groups within your match
   {
      Console.WriteLine(group.Value);
   }
}

This allows you to match multiple filenames in a single string, then loop through those matches, and grab each individual group from within the parent match. This makes a bit more sense than returning a single, flattened out array like some languages. Also, I'd consider giving your groups names:

Regex regx = new Regex(@"^.*(?<filename>vdi(?<version>[0-9]+\.[0-9]+)\.exe).*$");

Then, you can refer to groups by name:

string file = r.Groups["filename"].Value;
string ver = r.Groups["version"].Value;

This makes the code a bit more readable, and allows group offsets to change without breaking things.

Also, if you're always parsing only a single filename, there's no reason to loop through a MatchCollection at all. You can change:

MatchCollection results = regx.Matches("vdi1.0.exe");

To:

Match result = regx.Match("vdi1.0.exe");

To obtain a single Match object, and access each Group by name or index.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Mike - I didn't even know about naming groups. I'm doing it just like that now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.