使用正则表达式(C#)捕获第一个匹配项

5
这是我第一次接触C#,也是我有限的正则表达式经验之一。我在捕获特定表达式中的首个匹配项方面遇到了困难。我相信下面的示例会比言语更清楚地描述我想要做的事情。
Match extractor = (new Regex(@".*\d(?<name>.*)\d.*")).Match("This hopefully will pick up 1Bob9error1 as a name");
        Console.WriteLine(extractor.Groups["name"]);

我希望这个表达式输出"Bob"而不是"error"。
我有一种预感,这与匹配组前面的?有关,但我不确定在这种情况下?执行什么操作。如果能解释并提供一些帮助,那就太好了。
谢谢大家,你们不知道这个网站对像我这样的初学者有多大帮助。

(?<name>yourRegEx)表示一个被捕获的组,可以命名为"name"。这就是为什么您能够使用extractor.Groups["name"]的原因。 - nickytonline
4个回答

8
你的问题在于贪婪匹配。正则表达式中的.*会匹配到所有内容,包括"This hopefully will pick up 1Bob"。请尝试使用以下正则表达式:
\d(?<name>[^\d]+)\d

Chad,我建议你安装RegExWorkbench,http://code.msdn.microsoft.com/RegexWorkbench。这是一个由Eric Gunnerson制作的古老项目,但非常棒。如果你没有安装.NET 1.x框架,他提供了源代码,以便你可以使用已安装的框架进行编译。 - nickytonline
那真的捕获了“Bob”。太棒了。我认为我的问题是我把这个正则表达式当作必须匹配整个字符串来处理,而实际上我只是在询问它是否有匹配项。非常感谢。 - Chad
你必须记住,使用正则表达式时,“.”和“*”可能非常危险。当你编写正则表达式时,你真的需要知道你想要查找的内容,并且只查找那些内容。这需要时间,但一旦你始终如一地做到了这一点,你就会得到非常可靠的正则表达式。我还建议你访问这个网站http://www.regular-expressions.info,并阅读这本书《精通正则表达式》http://regex.info。 - nickytonline

3
匹配前面的元素零次或一次。等同于{0,1}。?是一个贪婪量词,其非贪婪版本是??。
来自这里。该网站包括正则表达式的速查表,查看您的表达式,我似乎无法确定可能出了什么问题。
我的假设是它可能匹配了您表达式的最后一个出现。

我可能错了,但我不认为在这种情况下“?”是一个量词。量词通常不是在表达式后面吗? - Chad
表达式没有问题,他只是看了一下它捕获的第二个值而不是第一个。 - Rory
@Chad 在这种情况下,问号表示一个命名组的开始(更具体地说,是名为"name"的组)。在大多数其他地方,它被用作量词。 - Rory

2
每个组项都有一个捕获集合,您可以使用以下方法访问组的第一个捕获:
extractor.Groups["name"].Captures[0]

每个捕获项都有一个值属性,该属性返回捕获的实际字符串值,还有一些其他有用的属性,例如捕获在原始字符串中开始的索引和捕获的长度。如果有疑问,请按F1键。 - Rory
嗯...有用的信息,但是Captures[0]仍然捕获了"error"。我的正则表达式有问题吗? - Chad

2

你的表达式周围的括号*字符是导致问题的原因。请记住,你不需要一个匹配整个字符串的正则表达式 - 你只希望它在特定模式出现时进行匹配。以下代码可行:

Regex pattern = new Regex(@"\d(?<name>.*?)\d");
MatchCollection matches = pattern.Matches("This hopefully will pick up 1Bob9error1 as a name");
Console.WriteLine(matches[0].Groups["name"]);

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