Home > Mobile >  C# LINQ Add to list every regex value group
C# LINQ Add to list every regex value group

Time:12-10

I have this code

Regex containsDelimitersInBrackets = new Regex(@"\[(.*?)\]");

foreach (Match match in containsDelimitersInBrackets.Matches(_sequence))
    _separator.Add(match.Groups[1].Value);
                

I'd like to use LINQ to add each value of each group to the _separator list.

I've tried this.

 _separator.AddRange(containsDelimitersInBrackets.Matches(_sequence).Where(x => x.Groups[1].Value));

but it doesn't work. What would be the correct way to do this?

CodePudding user response:

Matches can return 1 or more Matches, so you can get the group 1 value(s) from the Match(es) using Select and then flatten that collection using SelectMany to get each value of each group separately.

Then you can use addRange to add the collection to the _separator list.

For example

List<string> _separator = new List<string>(){"existing item"};
Regex containsDelimitersInBrackets = new Regex(@"\[([^][]*)]");

List<string> _sequence = new List<string>(){"test[1] test[2]", "test[123]"}
.SelectMany(s => 
    containsDelimitersInBrackets.Matches(s)
    .Select(m => 
        m.Groups[1].Value
    )
).ToList();

_separator.AddRange(_sequence);
_separator.ForEach(s => Console.WriteLine(s));

Output

item one
1
2
123

Note that instead of the non greedy quantifier, you can also use a negated character class to prevent some backtracking.

Regex containsDelimitersInBrackets = new Regex(@"\[([^][]*)]");

See a C# demo.

CodePudding user response:

You were close..

We don't use .Where to project value x (i.e. a Match object) into value y (i.e. a string), we use .Select

_separator.AddRange(containsDelimitersInBrackets
  .Matches(_sequence)
  .Cast<Match>()
  .Select(x => x.Groups[1].Value)
);

You also need a .Cast<T>() when working with old school xxxCollection classes to make LINQ work easily with the type returned from their enumerators.. Otherwise the compiler treats it as an enuemration of objects and you don't ver a very helpful intellisense. ( If you wrote foreach(var m in someMatchCollection) then m would be object.. When you write foreach(Match m in someMatchCollection) it takes the type hint from how you declared m)

  • Related