2011-04-23 14 views
18

To jest moje źródło ciąg:Przelotowe Regex zestawienia

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

To mój Regex Patern:

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

To moja klasa Element

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

To moja kolekcja Element ;

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

Chcę wypełnić tę listę pozycjami opartymi na łańcuchu źródłowym. To jest moja funkcja. To nie działa.

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 może być kilka małych błędów, takich jak brakujące litery to ten przykład, ponieważ jest to łatwiejsze wersja tego, co mam w mojej aplikacji.

Problem polega na tym, że w końcu mam tylko jedną pozycję w liście zamówień.

UPDATE

mam to działa. Thans o pomoc.

+2

Po prostu uruchomiłem - działa jak oczekiwano (3 pozycje na liście). – ChrisWue

+0

Znalazłem swój błąd. – Hooch

+2

Czy możesz to udostępnić? Może pomóc komuś, jeśli napotka na ten sam problem. – ChrisWue

Odpowiedz

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

Zwraca 3 mecze dla mnie. Twój problem musi być gdzie indziej.

8

Dla przyszłości chcę dokumentować powyższy kod przekształca się za pomocą deklaratywny podejście jako fragmentu kodu 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(); 

Z wyjściem:

List of matches

+0

Jaki program znajduje się na tym zrzucie ekranu? Czy to twój własny program? – Hooch

+1

Jest to generowane przez metodę rozszerzenia Dump() LinqPada. Możesz przykleić Dump() na końcu większości obiektów i wyświetli sformatowaną reprezentację obiektu. LinqPad to wyjątkowe narzędzie do pisania/oceny kodu C# http://www.linqpad.net/. Powyższy kod można skopiować i wkleić prosto do LinqPada i wygeneruje on tabelę. –

+1

Potem jestem jak, Lawl ... Zamierzam kliknąć "edytuj", aby zobaczyć przecenę za stworzenie tak pięknego stołu. – Suamere

5

do zajęcia tylko tytuł pytania ("zapętlanie przez mecze Regex"), możesz:

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

Spowoduje to "spłaszczenie" wszystkich przechwyconych wartości w dół do pojedynczej listy. Aby zachować grupy przechwytujące, użyj Select zamiast SelectMany, aby uzyskać listę list.