Resultaat van overeenkomsten van regex converteren naar een lijst met tekenreeksen

Hoe kan ik de lijst met wedstrijdresultaten van regex converteren naar List<string>? Ik heb deze functie, maar het genereert altijd een uitzondering,

Kan object van het type ‘System.Text.RegularExpressions.Match’ niet casten
om ‘System.Text.RegularExpressions.CaptureCollection’ te typen.

public static List<string> ExtractMatch(string content, string pattern)
{
    List<string> _returnValue = new List<string>();
    Match _matchList = Regex.Match(content, pattern);
    while (_matchList.Success)
    {
        foreach (Group _group in _matchList.Groups)
        {
            foreach (CaptureCollection _captures in _group.Captures) // error
            {
                foreach (Capture _cap in _captures)
                {
                    _returnValue.Add(_cap.ToString());
                }
            }
        }
    }
    return _returnValue;
}

Als ik deze string heb,

I have a dog and a cat.

regex

dog|cat

Ik wil dat de functie het resultaat teruggeeft in List<string>

dog
cat

Antwoord 1, autoriteit 100%

Met de Regex die je hebt, moet je Regex.Matchesgebruiken om de definitieve lijst met strings te krijgen zoals je wilt:

MatchCollection matchList = Regex.Matches(Content, Pattern);
var list = matchList.Cast<Match>().Select(match => match.Value).ToList();

Antwoord 2, autoriteit 12%

Als je alleen een lijst met Regex-overeenkomsten wilt, kun je:

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

Hiermee worden alle vastgelegde waarden “afgeplat” tot één enkele lijst. Om vastleggroepen te onderhouden, gebruikt u Selectin plaats van SelectManyom een ​​lijst met lijsten te krijgen.


Antwoord 3, autoriteit 5%

Een mogelijke oplossing met Linq:

using System.Linq;
using System.Text.RegularExpressions;
static class Program {
    static void Main(string[] aargs) {
        string value = "I have a dog and a cat.";
        Regex regex = new Regex("dog|cat");
        var matchesList = (from Match m in regex.Matches(value) select m.Value).ToList();
    }
}

Antwoord 4

Hier is nog een oplossing die goed in uw code past.

while (_matchList.Success)
{
    _returnValue.Add(_matchList.Value);
    _matchList = _matchList.NextMatch();
}

Antwoord 5

Historisch gezien hebben de Regex-collecties de generieke collectie-interfaces niet geïmplementeerd, en de LINQ-uitbreidingsmethoden die u gebruikt, werken op de generieke interfaces. MatchCollection is bijgewerkt in .NET Core om IList te implementeren, en kan dus worden gebruikt met de Selectextension-methode, maar wanneer u overstapt naar .NET Standard 2.0, is die interface-implementatie er niet, en dus kunt u Select niet zomaar aanroepen. In plaats daarvan moet u de extensies LINQCastof OfTypegebruiken om te converteren naar een IEnumerable, en dan daar kun je Selectvoor gebruiken. Ik hoop dat dat helpt.

Voorbeeld

Regex wordMatcher = new Regex(@"\p{L}+");
return wordMatcher.Matches(text).Cast<Match>().Select(c => c.Value);
Regex wordMatcher = new Regex(@"\p{L}+");
return wordMatcher.Matches(text).OfType<Match>().Select(c => c.Value);

Antwoord 6

var regex = new Regex("{([A-Za-z])*}");
var result= regex.Matches(text).Where(p => p.Success).Select(p => p.Value).ToList();

Other episodes