Search code examples
regex.net-2.0

Capturing a repeated group


I am attempting to parse a string like the following using a .NET regular expression:

H3Y5NC8E-TGA5B6SB-2NVAQ4E0

and return the following using Split: H3Y5NC8E TGA5B6SB 2NVAQ4E0

I validate each character against a specific character set (note that the letters 'I', 'O', 'U' & 'W' are absent), so using string.Split is not an option. The number of characters in each group can vary and the number of groups can also vary. I am using the following expression:

([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8}-?){3}

This will match exactly 3 groups of 8 characters each. Any more or less will fail the match. This works insofar as it correctly matches the input. However, when I use the Split method to extract each character group, I just get the final group. RegexBuddy complains that I have repeated the capturing group itself and that I should put a capture group around the repeated group. However, none of my attempts to do this achieve the desired result. I have been trying expressions like this:

(([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8})-?){4}

But this does not work.

Since I generate the regex in code, I could just expand it out by the number of groups, but I was hoping for a more elegant solution.


Please note that the character set does not include the entire alphabet. It is part of a product activation system. As such, any characters that can be accidentally interpreted as numbers or other characters are removed. e.g. The letters 'I', 'O', 'U' & 'W' are not in the character set.

The hyphens are optional since a user does not need top type them in, but they can be there if the user as done a copy & paste.


Solution

  • I have discovered the answer I was after. Here is my working code:

        static void Main(string[] args)
        {
            string pattern = @"^\s*((?<group>[ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8})-?){3}\s*$";
            string input = "H3Y5NC8E-TGA5B6SB-2NVAQ4E0";
            Regex re = new Regex(pattern);
            Match m = re.Match(input);
    
            if (m.Success)
                foreach (Capture c in m.Groups["group"].Captures)
                    Console.WriteLine(c.Value);
        }