2

I am having a regex to identify some named groups. There are a few cases which have multiple groups with different patterns. The problem is to have all named groups into corresponding lists. The constraint is that I cannot have more than one regex and I cannot call execute the regex more than once. I have tried following code, but it always returns second pattern:

        Regex reg = new Regex(@"(?<n1>pattern_n1_1) (?<n2>pattern_n2_1) (?<n1>pattern_n1_2) (?<n2>pattern_n1_2)", RegexOptions.IgnoreCase);

        String str = "pattern_n1_1 pattern_n2_1 pattern_n1_2 pattern_n1_2";

        List<String> matchedText = new List<string>();
        List<String> string_n1 = new List<string>();
        List<String> string_n2 = new List<string>();

        MatchCollection mc = reg.Matches(str);
        if (mc != null)
        {
            foreach (Match m in mc)
            {
                matchedText.Add(m.Value.Trim());
                string_n1.Add(m.Groups["n1"].Value);
                string_n2.Add(m.Groups["n2"].Value);
            }
        }

Here the list string_n1 and string_n2 has one element each. string_n1 has "pattern_n1_2" and string_n2 has "pattern_n2_2". However, I require both "pattern_n1_1" and "pattern_n1_2" to be in string_n1 AND both "pattern_n2_1" and "pattern_n2_2" to be in string_n2

4
  • not the solution, but I find this tool very handy when it comes to debugging regex strings. Perhaps it can be of some help to you. Commented Dec 16, 2014 at 14:53
  • 1
    @NickOtten: Don't suggest regexr on a C# question. It is tool for JS RegExp. For .NET regex, there is regexhero and regexstorm, also regexplanet, though from my experience, regexstorm is the best in displaying the full power of .NET regex. Commented Dec 16, 2014 at 15:20
  • There seems to be a typo in your code. Going by the text of your question, I believe he last token was supposed to be pattern_n2_2, not pattern_n1_2. The error is repeated in the corresponding portion of the regex. Commented Dec 17, 2014 at 2:41
  • @nhahtdh I will look into the tools suggested Thank you. I used to use debuggex with PCRE engine in this tool. Commented Dec 17, 2014 at 5:24

2 Answers 2

5

There is no need to change your regex. You only need to change the way you retrieve the result from the capturing groups.

Since you have multiple capturing groups under the same name, in order to retrieve all captures done under that name, you need to loop through all Capture in Groups["n1"].Captures, instead of accessing a single capture with Groups["n1"].Value.

MatchCollection mc = reg.Matches(str);
if (mc != null)
{
    foreach (Match m in mc)
    {
        matchedText.Add(m.Value.Trim());

        foreach (Capture c in m.Groups["n1"].Captures) {
            string_n1.Add(c.Value);
        }

        foreach (Capture c in m.Groups["n2"].Captures) {
            string_n2.Add(c.Value);
        }
    }
}

Demo on ideone

This is a feature, as far as I know, unique to .NET Regex API. None of the other flavors offers an API to go through all matches of a repeated capturing group:

^\w+(?: (\w+))+$

Other flavors only return the last capture for the capturing group 1 in the above example. .NET allows you to extract all captures by a capturing group.

And although there are flavors allowing you to define the same name for different capturing groups, other flavors only allow you to access to one of the captures when querying via the group name.

Reference

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

1 Comment

Thanks for the elaborate answer. The code is working as expected.
0

Depending on the specifics, the follow may work for your needs, but is not generalized solution:

Regex reg = new Regex(@"((?<n1>(pattern_n1_1|pattern_n1_2)) (?<n2>(pattern_n2_1|pattern_n1_2)) ){2}", RegexOptions.IgnoreCase);

This will capture a bit more than the original, in that pattern_n1_2 would be caught as the fourth "group" in this version for example, but not the original.

Comments

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.