Подтвердить что ты не робот

С# foreach loop с ключом

В PHP я могу использовать цикл foreach, так что у меня есть доступ к ключу и значению, например:

foreach($array as $key => $value)

У меня есть следующий код:

Regex regex = new Regex(pattern);
MatchCollection mc = regex.Matches(haystack);
for (int i = 0; i < mc.Count; i++)
{
     GroupCollection gc = mc[i].Groups;
     Dictionary<string, string> match = new Dictionary<string, string>();
     for (int j = 0; j < gc.Count; j++)
     {
        //here
     }
     this.matches.Add(i, match);
}

at //here Я хотел бы match.add(key, value), но я не могу понять, как получить ключ от GroupCollection, который в этом случае должен быть именем группы захвата. Я знаю, что gc["goupName"].Value содержит значение совпадения.

4b9b3361

Ответ 1

В .NET имена групп доступны для экземпляра Regex:

// outside all of the loops
string[] groupNames = regex.GetGroupNames();

Затем вы можете выполнить итерацию на основе этого:

Dictionary<string, string> match = new Dictionary<string, string>();
foreach(string groupName in groupNames) {
    match.Add(groupName, gc[groupName].Value);
}

Или, если вы хотите использовать LINQ:

var match = groupNames.ToDictionary(
            groupName => groupName, groupName => gc[groupName].Value);

Ответ 2

В С# 3 вы также можете использовать LINQ для выполнения такой обработки коллекции. Классы для работы с регулярными выражениями реализуют только не общие IEnumerable, поэтому вам нужно указать несколько типов, но они все еще довольно элегантны.

Следующий код дает вам набор словарей, которые содержат имя группы в качестве ключа и совпадающее значение в качестве значения. Он использует предложение Marc использовать ToDictionary, за исключением того, что он указывает имя группы в качестве ключа (я думаю, что код Marc использует совпадающее значение в качестве имени ключа и группы в качестве значения).

Regex regex = new Regex(pattern);
var q =
  from Match mci in regex.Matches(haystack)
  select regex.GetGroupNames().ToDictionary(
    name => name, name => mci.Groups[name].Value);

Затем вы можете просто присвоить результат своему this.matches.

Ответ 3

Вы не можете получить доступ к имени группы напрямую, вам нужно использовать GroupNameFromNumber для экземпляра регулярного выражения (см. документ).

Regex regex = new Regex(pattern);
MatchCollection mc = regex.Matches(haystack);
for (int i = 0; i < mc.Count; i++)
{
     GroupCollection gc = mc[i].Groups;
     Dictionary<string, string> match = new Dictionary<string, string>();
     for (int j = 0; j < gc.Count; j++)
     {
        match.Add(regex.GroupNameFromNumber(j), gc[j].Value);
     }
     this.matches.Add(i, match);
}