2010-02-28 14 views
11

In PHP è possibile utilizzare un ciclo foreach in modo tale che io ho accesso sia la chiave e il valore, ad esempio:C ciclo # foreach con valore chiave

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

ho il seguente codice:

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); 
} 

a //here Mi piacerebbe match.add(key, value) ma non riesco a capire come ottenere la chiave da GroupCollection, che in questo caso dovrebbe essere il nome del gruppo di acquisizione. So che gc["goupName"].Value contiene il valore della partita.

+0

Qual è la chiave, qual è il valore? – kennytm

risposta

10

In .NET, i nomi dei gruppi sono disponibili contro l'Regex esempio:

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

Poi si può iterare sulla base di questo:

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

Oppure, se si desidera utilizzare LINQ :

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

Non è possibile accedere direttamente al nome del gruppo, è necessario utilizzare GroupNameFromNumber sull'istanza di espressioni regolari (see doc).

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); 
} 
4

In C# 3, è inoltre possibile utilizzare LINQ per eseguire questo tipo di elaborazione della raccolta. Le classi per lavorare con le espressioni regolari implementano solo IEnumerable non generico, quindi è necessario specificare un paio di tipi, ma è ancora abbastanza elegante.

Il seguente codice fornisce una raccolta di dizionari che contengono il nome del gruppo come chiave e il valore corrispondente come valore. Utilizza il suggerimento di Marc per utilizzare ToDictionary, tranne che specifica il nome di gruppo come chiave (I pensa a che il codice di Marc utilizza il valore corrispondente come chiave e il nome del gruppo come valore).

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); 

Quindi è possibile assegnare il risultato al proprio this.matches.

+0

@Tomas - risolto; buon posto –