web-dev-qa-db-fra.com

Boucle à travers des correspondances d'expression régulière

Voici ma chaîne source:

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

Voici mon Regex Patern:

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

Ceci est ma classe d'objets

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

Ceci est ma collection d'objets;

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

Je veux remplir cette liste avec des éléments basés sur la chaîne source. C'est ma fonction. Ça ne fonctionne pas.

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

Il pourrait y avoir quelques petites erreurs comme la lettre manquante dans cet exemple, car il s'agit d'une version plus facile de ce que j'ai dans mon application.

Le problème est qu'à la fin je n'ai qu'un seul article dans OrderList.

MISE À JOUR

Je l'ai fait fonctionner. Merci pour votre aide.

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

Renvoie 3 correspondances pour moi. Votre problème doit être ailleurs.

43
mpen

Pour référence future, je souhaite documenter le code ci-dessus converti en utilisant une approche déclarative comme extrait de code 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();

Avec sortie:

List of matches

11
David Clarke

Pour répondre uniquement au titre de la question ("parcourir les correspondances Regex"), vous pouvez:

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

Cela "aplatira" toutes les valeurs capturées en une seule liste. Pour conserver les groupes de capture, utilisez Select plutôt que SelectMany pour obtenir une liste de listes.

5
drzaus