C# 正则表达式字符串解析

7

我已经写好了表达式,但是每次运行代码时,我都会得到整个字符串和一堆空值:

Regex regex = new Regex(@"y=\([0-9]\)\([0-9]\)(\s|)\+(\s+|)[0-9]");
Match match = regex.Match("y=(4)(5)+6");

for (int i = 0; i < match.Length; i++)
{
    MessageBox.Show(i+"---"+match.Groups[i].Value);
}

期望输出: 4、5、6 (在不同的MessageBoxes中)

实际输出: y=(4)(5)+6

它会查找输入的字符串是否正确,但一旦成功,我就无法获取特定的值(即4、5和6)。我该怎么做才能得到这段代码呢?这可能是非常简单的事情,但我尝试查看MSDN match.NextMatch文章,也没有帮助。

谢谢!


1
我不太明白这个问题 - 你是在寻找匹配不正确格式的字符串的正则表达式吗? - Oded
正则表达式匹配字符串很好 - 当所有变量都被填充时,它会返回true(或match.Success)。然而,我想要的是获取每个单独的值。 - Scott
你尝试过检查 te.Captures 吗?http://msdn.microsoft.com/zh-cn/library/twcw2f1c.aspx - Caspar Kleijne
5个回答

5

当前情况下,您没有指定任何组。(除了空格周围的组。)

您可以使用括号指定组。您当前使用的括号具有反斜杠,因此它们被用作匹配的一部分。在其中添加额外的一组括号。

像这样:

new Regex(@"y=\(([0-9]+)\)\(([0-9]+)\)\+([0-9]+)");

并且包含空格:

new Regex(@"y\s*=\s*\(([0-9]+)\)\s*\(([0-9]+)\)\s*\+\s*([0-9]+)");

这样做可以使各部分之间的空格变得可选,因为 * 表示 0 或多个。这比之前提到的 (?:\s+|) 更好,因为你不需要一个空格组。它也更好,因为 | 的含义是“或者”。\s+| 所表达的意思是“一个或多个空格或者什么都没有”。这与\s* 相同,后者为“零个或多个空格”。
此外,我使用了 [0-9]+,因为这表示一个或多个数字。这允许匹配包含多个数字的数字,例如10或100。另外需要注意的是,使用[0-9]比\d更好,因为\d指的不仅仅是我们常用的数字。

1
刚刚更新了我的答案,让它更加清晰明了。希望你现在能够理解你的模式中每个部分的作用。 - LTAcosta

4

您需要给您的组命名,以便以后可以调用它们。 如何在.NET Regex中访问已命名的捕获组?

Regex regex = new Regex(@"y=\((?<left\>[0-9])\)\((?<right>[0-9])\)(\s|)\+(\s+|)(?<offset>[0-9])");

然后您可以像这样将它们拉出来:
regex.Match("y=(4)(5)+6").Groups["left"];

3

使用(命名)捕获组。对于您不想捕获的组,您还需要使用(?:)而不是()。否则,它们也将出现在结果组中。

Regex regex = new Regex(@"y=(\([0-9]\))((\([0-9]\))(?:\s|)\+(?:\s+|)([0-9])");
Match match = regex.Match("y=(4)(5)+6");
Console.WriteLine("1: " + match.Groups[1] + ", 2: " + match.Groups[2] + ", 3: " + match.Groups[3]);

如果模式找到匹配项,则该匹配项的组将被写入属性中,可以通过索引访问该属性(索引0包含完整匹配项)。

您还可以为这些组命名,以使代码更易读:

Regex regex = new Regex(@"y=(?<first>\([0-9]\))(?<second>(\([0-9]\))(?:\s|)\+(?:\s+|)(?<third>[0-9])");

现在,您可以使用match.Groups["first"]等来访问捕获组。


2

C# 不是我的专业领域,但这个方法可能有效:

@"y=\(([0-9])\)\(([0-9])\)(?:\s|)\+(?:\s+|)([0-9])"

基本上这是您原始的正则表达式,但数字周围有捕获组,并且不需要捕获的组已更改为非捕获组:(?: ... )


2

Group[0]总是会给出匹配的字符串,null值来自于(\s|)。

这样写是正确的:y=\((\d)\)\((\d)\)\s*\+\s*(\d)

从1开始的组数计算你使用的括号,但如果你转义它们,它们就不计入(因为你告诉它它们只是要匹配的文本),所以那些数字需要它们自己的括号。当像?或*这样的东西更合适时,使用(x|)并不是一个好主意,因为你没有捕获那一部分。

这样写可能会更好y=\((\d+)\)\((\d+)\)\s*\+\s*(\d+),因为它支持大于十的值。


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