正则表达式捕获组

3

使用以下正则表达式:

InitValue\((\w*)\)

以及测试字符串:

InitValue(Input1)

我得到了以下结果:
Full match: InitValue(Input1)
Group1: Input1

使用以下正则表达式:

InitValue\((\w*)\s*,\s*(\w*)\)

以及测试字符串:

InitValue(Input1, Input2)

I get:

Full match: InitValue(Input1, Input2)
Group1: Input1
Group2: Input2

现在我想捕获任意数量的参数到InitValue方法中。传递给InitValue的参数数量是未知的。

Full match: InitValue(Input1, Input2, ..., Inputn)
Group1: Input1
Group2: Input2
....
Groupn: Inputn

当然,由于我不知道参数的数量,所以不能在我的正则表达式中重复下面的模式:
\s*,\s*(\w*)

如何编写一个正则表达式,使其输出n个捕获组?

我在C#代码中使用正则表达式(Regex,Match)...

4个回答

1
在.NET中可以实现这个功能 - 您可以使用单个捕获组Group,然后访问Group的Captures集合以查看它捕获的所有项,而不仅仅是最终的Value
您需要编写一个可以重复匹配参数的正则表达式,类似于:
InitValue\((?:(\w+)\s*(?:,(?!\s*\))|(?=\s*\)))\s*)*\)

尝试使用Debuggex演示进行调整,以达到您想要的匹配效果。


1
static void GetParams()
{
    int x = 0;
    var strings = new[]
    {
        "InitValue()",
        "InitValue(Input1)",
        "InitValue(Input1, Input2, Input3, Input4)"
    };

    var pattern = @"(\w+)\((?:(\w+)(?:,?\s*))*\)";

    foreach (var s in strings)
    {
        WriteLine($"String: '{s}'");
        var match = Regex.Match(s, pattern);
        if (match.Success)
        {
            WriteLine($"\tMethod: '{match.Groups[1].Value}'");
            WriteLine("\tParameters:");
            var captures = match.Groups[2].Captures;
            if (captures.Count > 0)
            {
                x = 0;
                foreach (Capture capture in captures)
                {
                    WriteLine($"\t\tParam {++x}: '{capture.Value}'");
                }
            }
            else
            {
                WriteLine("\t\tNo params found.");
            }

            WriteLine();
        }

        else
            WriteLine("No matches found.");
    }
}

/*
Output:

String: 'InitValue()'
        Method: 'InitValue'
        Parameters:
                No params found.

String: 'InitValue(Input1)'
        Method: 'InitValue'
        Parameters:
                Param 1: 'Input1'

String: 'InitValue(Input1, Input2, Input3, Input4)'
        Method: 'InitValue'
        Parameters:
                Param 1: 'Input1'
                Param 2: 'Input2'
                Param 3: 'Input3'
                Param 4: 'Input4'
*/

1

.NET支持无限回溯后发现(?<=。除了获得捕获组之外,另一个选项是获得匹配项:

(?<=\bInitValue\([^()]*)[^, ]+(?=[^()]*\))

解释

  • (?<= 正向后行断言,检查左侧是否匹配:
    • \bInitValue\([^()]* 匹配单词边界,InitValue( 然后是0个或多个非 ()
  • ) 关闭正向后行断言
  • [^, \t]+ 负字符类,匹配1个或多个非空格或逗号
  • (?= 正向前瞻,检查右侧是否匹配:
    • [^()]*\) 匹配0个或多个非 (),然后匹配 )
  • ) 关闭正向前瞻

例如:

string pattern = @"(?<=\bInitValue\([^()]*)[^, ]+(?=[^()]*\))";
string str = "InitValue(Input1, Input2, Input3)";            
foreach (Match m in Regex.Matches(str, pattern))
{
    Console.WriteLine(m.Value);
}

结果

Input1
Input2
Input3

看一下正则表达式演示 | C#演示

0

不要让任何人告诉你什么是不可能的,什么是可能的。

enter image description here

你需要稍微动一下它,但我认为它可以指导你 =D。

编辑,回答你的问题。 b.Count 将给出匹配项的数量。
编辑2,我发布了图片以显示调试信息。但这里是 sibarist 的代码。

string bar = "test, othertest";
Regex reg = new Regex(@"[\w]+");

MatchCollection b = reg.Matches(bar);

string b1 = b[0].Value;
string b2 = b[1].Value;

int numberGroups = b.Count;

编辑3,根据评论的建议,这是完整的解决方案,您需要使用另一个RegexSubstring清除InitValue(*)部分。

string input = "InitValue(test, othertest, bleh, blehTest, foo)";

Regex regArgs = new Regex(@"(?:InitValue\()(.*)(?:\))");
Match matchArgs = regArgs.Match(input);

string valueArgs = matchArgs.Groups[1].Value;

Regex reg = new Regex(@"[\w]+");

MatchCollection b = reg.Matches(valueArgs);

string b1 = b[0].Value;
string b2 = b[1].Value;

int numberGroups = b.Count;

请展示如何将此技术应用于测试字符串:InitValue(Input1, Input2, Input3, Input4) - mrzasa
你是什么意思?就像我所说的,这只是一个示例,并不是完整的解决方案,但已经足够接近了。如果你的意思是当它写成InitValue时不可能删除它,那么是的,你是对的,但那远非不可能 =D。你可以轻松地用Substring删除InitValue(*)并保留参数。 - Nekeniehl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接