Wie erhalte ich den Namen der erfassten Gruppen in einem C # -Regex?

97

Gibt es eine Möglichkeit, den Namen einer erfassten Gruppe in C # abzurufen?

string line = "No.123456789  04/09/2009  999";
Regex regex = new Regex(@"(?<number>[\d]{9})  (?<date>[\d]{2}/[\d]{2}/[\d]{4})  (?<code>.*)");

GroupCollection groups = regex.Match(line).Groups;

foreach (Group group in groups)
{
    Console.WriteLine("Group: {0}, Value: {1}", ???, group.Value);
}

Ich möchte dieses Ergebnis erhalten:

Gruppe: [Ich weiß nicht, was hier hingehen soll], Wert: 123456789 04/09/2009 999
Gruppe: Nummer, Wert: 123456789
Gruppe: Datum, Wert: 04/09/2009
Gruppe: Code, Wert: 999
Luiz Damim
quelle

Antworten:

127

Verwenden Sie GetGroupNames , um die Liste der Gruppen in einem Ausdruck und diese dann zu durchlaufen, wobei Sie die Namen als Schlüssel für die Gruppensammlung verwenden.

Beispielsweise,

GroupCollection groups = regex.Match(line).Groups;

foreach (string groupName in regex.GetGroupNames())
{
    Console.WriteLine(
       "Group: {0}, Value: {1}",
       groupName,
       groups[groupName].Value);
}
Jeff Yates
quelle
9
Danke dir! Genau das, was ich wollte. Ich hätte nie gedacht, dass dies im Regex-Objekt sein würde :(
Luiz Damim
22

Der sauberste Weg, dies zu tun, ist die Verwendung dieser Erweiterungsmethode:

public static class MyExtensionMethods
{
    public static Dictionary<string, string> MatchNamedCaptures(this Regex regex, string input)
    {
        var namedCaptureDictionary = new Dictionary<string, string>();
        GroupCollection groups = regex.Match(input).Groups;
        string [] groupNames = regex.GetGroupNames();
        foreach (string groupName in groupNames)
            if (groups[groupName].Captures.Count > 0)
                namedCaptureDictionary.Add(groupName,groups[groupName].Value);
        return namedCaptureDictionary;
    }
}


Sobald diese Erweiterungsmethode eingerichtet ist, können Sie Namen und Werte wie folgt abrufen:

    var regex = new Regex(@"(?<year>[\d]+)\|(?<month>[\d]+)\|(?<day>[\d]+)");
    var namedCaptures = regex.MatchNamedCaptures(wikiDate);

    string s = "";
    foreach (var item in namedCaptures)
    {
        s += item.Key + ": " + item.Value + "\r\n";
    }

    s += namedCaptures["year"];
    s += namedCaptures["month"];
    s += namedCaptures["day"];
Whitneyland
quelle
9

Seit .NET 4.7 ist eine Group.NameEigenschaft verfügbar .

Jozef Benikovský
quelle
7

Sie sollten verwenden GetGroupNames();und der Code sieht ungefähr so ​​aus:

    string line = "No.123456789  04/09/2009  999";
    Regex regex = 
        new Regex(@"(?<number>[\d]{9})  (?<date>[\d]{2}/[\d]{2}/[\d]{4})  (?<code>.*)");

    GroupCollection groups = regex.Match(line).Groups;

    var grpNames = regex.GetGroupNames();

    foreach (var grpName in grpNames)
    {
        Console.WriteLine("Group: {0}, Value: {1}", grpName, groups[grpName].Value);
    }
Eran Betzalel
quelle