简体   繁体   中英

Parentheses not capturing c# regex groups

Trying to extract the name and id from a string with the following code:

Regex.Matches
    "id: 123456, name: some dude",
    @"^id: (?<id>\d+), name: (?<name>[a-z]+(\s[a-z]+)?)"
);

However, the number of groups and captures is 1, and there are no named captures. What am I missing?

Edit: Found the answer (thanks everyone!) but for future reference, it turns out it's because I completely misunderstood the API and was accessing the matches wrong. I was doing stuff like this:

Console.WriteLine(matches.Count); // 1
foreach( Group g in matches ) {
    Console.WriteLine(g.Captures.Count); //1
    foreach( Capture c in g.Captures ) {
        Console.WriteLine(c.Value); // The whole string
    }
}

But now I know better!

There is probably something wrong with the way you look for matches as your regex look ok:

Regex.Matches(
    "id: 123456, name: some dude",
    @"^id: (?<id>\d+), name: (?<name>[a-z]+(\s[a-z]+)?)"
)[0].Groups.Cast<Group>().Skip(2).Select(x => new {x.Name, x.Value})

Produces:

Name  Value
    id    123456 
    name  some dude

If you just need particular one - Regex.Matches(...)[0].Groups[2] or .Groups["id"] .

Note that your code uses Matches that returns all matches, if you just expect single match - use Match as shown in Michael Randall answer

This works just fine

String sample = "id: 123456, name: some dude";
Regex regex = new Regex(@"^id: (?<id>\d+), name: (?<name>[a-z]+(\s[a-z]+)?)");

Match match = regex.Match(sample);

if (match.Success)
{
   Console.WriteLine(match.Groups["id"].Value);
   Console.WriteLine(match.Groups["name"].Value);
}

And when .Net Fiddle works again you can demo it here


For Completness

Regex.Match Method (String)

Searches the specified input string for the first occurrence of the regular expression specified in the Regex constructor.

Regex.Matches Method

Searches an input string for all occurrences of a regular expression and returns all the matches.

Match.Groups Property

Gets a collection of groups matched by the regular expression. Groups can then be retrieved from the GroupCollection object

GroupCollection.Item Property (String)

Enables access to a member of the collection by string index. GroupName can be either the name of a capturing group that is defined by the (?<name>) element in a regular expression, or the string representation of the number of a capturing group that is defined by a grouping construct

You should use Match instead of Matches , and use non-capturing groups (?:) in your regex.

Regex demo

String input = "id: 123456, name: some dude";

var output = Regex.Match(input, @"^id: (?<id>\d+), name: (?<name>.+)");

System.Console.WriteLine(output.Groups["id"]);
System.Console.WriteLine(output.Groups["name"]);

Output:

123456 
some dude

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM