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

har*_*hit 2 .net c# 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);
            }
        }
Run Code Online (Sandbox Code Playgroud)

这里的列表string_n1string_n2各有一个元素。string_n1具有“pattern_n1_2”和string_n2“pattern_n2_2”。但是,我要求“pattern_n1_1”和“pattern_n1_2”都在string_n1并且“pattern_n2_1”和“pattern_n2_2”都在string_n2

nha*_*tdh 5

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

由于您在同一个名称下有多个捕获组,为了检索在该名称下完成的所有捕获,您需要循环遍历所有Capturein 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ideone 上的演示

据我所知,这是 .NET Regex API 独有的功能。其他风格都没有提供 API 来遍历重复捕获组的所有匹配项:

^\w+(?: (\w+))+$
Run Code Online (Sandbox Code Playgroud)

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

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

参考