如何在.net正则表达式中使用两个具有相同名称的命名组?

时间:2014-12-16 14:40:53

标签: c# .net regex

我正在使用正则表达式来识别一些命名组。有少数情况下有多个具有不同模式的组。问题是将所有命名组都放入相应的列表中。限制是我不能有多个正则表达式,我不能多次调用执行正则表达式。我尝试过以下代码,但它总是返回第二种模式:

        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);
            }
        }

此处列表string_n1string_n2各有一个元素。 string_n1有&#34; pattern_n1_2&#34;并且string_n2有&#34; pattern_n2_2&#34;。但是,我需要&#34; pattern_n1_1&#34;和&#34; pattern_n1_2&#34;在string_n1和&#34; pattern_n2_1&#34;和&#34; pattern_n2_2&#34;在string_n2

2 个答案:

答案 0 :(得分:2)

无需更改正则表达式。您只需要更改从捕获组中检索结果的方式。

由于您有多个同名的捕获组,为了检索在该名称下完成的所有捕获,您需要遍历Capture中的所有Groups["n1"].Captures,而不是访问单个捕获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

据我所知,这是.NET Regex API独有的功能。其他任何一种都没有提供API来完成重复捕获组的所有匹配:

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

其他风格仅返回上例中捕获组1的最后一次捕获。 .NET允许您通过捕获组提取所有捕获。

虽然有些风格允许您为不同的捕获组定义相同的名称,但其他风格只允许您在通过组名查询时访问其中一个捕获。

参考

答案 1 :(得分:0)

根据具体情况,以下可能可以满足您的需求,但不是通用解决方案:

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

这将捕获比原始更多一点,因为pattern_n1_2将被捕获为第四个&#34;组&#34;例如,在此版本中,但不是原始版本。