2011-04-23 18 views
18

Questa è la mia stringa di origine:Looping attraverso regex

<box><3> 
<table><1> 
<chair><8> 

Questo è il mio Regex Patern:

<(?<item>\w+?)><(?<count>\d+?)> 

Questa è la mia classe Item

class Item 
{ 
    string Name; 
    int count; 
    //(...) 
} 

Questa è la mia collezione Articolo ;

List<Item> OrderList = new List(Item); 

Desidero popolare questa lista con voci basate sulla stringa di origine. Questa è la mia funzione. La sua non funziona.

Regex ItemRegex = new Regex(@"<(?<item>\w+?)><(?<count>\d+?)>", RegexOptions.Compiled); 
      foreach (Match ItemMatch in ItemRegex.Matches(sourceString)) 
      { 
       Item temp = new Item(ItemMatch.Groups["item"].ToString(), int.Parse(ItemMatch.Groups["count"].ToString())); 
       OrderList.Add(temp); 
      } 

Threre potrebbero essere alcuni piccoli errori come lettera mancante in questo esempio, perché questa è la versione più semplice di quello che ho in mio app.

Il problema è che alla fine ho solo un elemento in OrderList.

UPDATE

ho capito di lavoro. Thans for help.

+2

Appena eseguito, funziona come previsto (3 elementi nell'elenco). – ChrisWue

+0

Ho trovato il mio errore. – Hooch

+2

Puoi condividerlo? Potrebbe aiutare qualcuno se sta incontrando lo stesso problema. – ChrisWue

risposta

33
class Program 
{ 
    static void Main(string[] args) 
    { 
     string sourceString = @"<box><3> 
<table><1> 
<chair><8>"; 
     Regex ItemRegex = new Regex(@"<(?<item>\w+?)><(?<count>\d+?)>", RegexOptions.Compiled); 
     foreach (Match ItemMatch in ItemRegex.Matches(sourceString)) 
     { 
      Console.WriteLine(ItemMatch); 
     } 

     Console.ReadLine(); 
    } 
} 

restituisce 3 partite per me. Il tuo problema deve essere altrove.

8

Per riferimento futuro voglio documentare il codice sopra convertito utilizzando un approccio dichiarativo come un frammento di codice LINQPad:

var sourceString = @"<box><3> 
<table><1> 
<chair><8>"; 
var count = 0; 
var ItemRegex = new Regex(@"<(?<item>[^>]+)><(?<count>[^>]*)>", RegexOptions.Compiled); 
var OrderList = ItemRegex.Matches(sourceString) 
        .Cast<Match>() 
        .Select(m => new 
        { 
         Name = m.Groups["item"].ToString(), 
         Count = int.TryParse(m.Groups["count"].ToString(), out count) ? count : 0, 
        }) 
        .ToList(); 
OrderList.Dump(); 

Con uscita:

List of matches

+0

Quale programma si trova su quello screenshot? È il tuo programma? – Hooch

+1

Generato dal metodo di estensione Dump() di LinqPad. È possibile inserire Dump() alla fine della maggior parte degli oggetti e verrà visualizzata una rappresentazione formattata dell'oggetto. LinqPad è solo uno strumento eccezionale per scrivere/valutare il codice C# http://www.linqpad.net/. Il codice sopra può essere copiato e incollato direttamente in LinqPad e genererà la tabella. –

+1

Allora mi piacciono tutti, lawl ... clicco su "edit" per vedere il markdown per creare un tavolo così carino. – Suamere

5

Per affrontare solo il titolo della domanda ("looping attraverso le partite Regex"), è possibile:

var lookfor = @"something (with) multiple (pattern) (groups)"; 
var found = Regex.Matches(source, lookfor, regexoptions); 
var captured = found 
       // linq-ify into list 
       .Cast<Match>() 
       // flatten to single list 
       .SelectMany(o => 
        // linq-ify 
        o.Groups.Cast<Capture>() 
         // don't need the pattern 
         .Skip(1) 
         // select what you wanted 
         .Select(c => c.Value)); 

Questo "appiattirà" tutti i valori acquisiti in un unico elenco. Per mantenere i gruppi di cattura, utilizzare Select anziché SelectMany per ottenere un elenco di elenchi.

Problemi correlati