I like to use regex and to do that such as for dogs:
var animals = new List<string>()
{ "japanese dog", "spanish dog", "english cat", "french cat" };
var dogs = animals.Where(type => Regex.IsMatch(type, "dog", RegexOptions.IgnoreCase))
.ToList();
// Returns {"japanese dog", "spanish dog" }
Why Regex you may ask, because its flexible and powerful...let me show:
Let us do some more advance linq work by having them sorted using the ToLookup
extension and regex such as
var sortedbyDogs
= animals.ToLookup(type => Regex.IsMatch(type, "dog", RegexOptions.IgnoreCase));
which is grouped in memory like this:

Then just extract cats such as
var cats = sortedbyDogs[false].ToList()

then pass in true
for dogs.
But why split it by a boolean, what if there are more animals? Lets add a lemur to the list such as … "french cat", "Columbian Lemur" };
we do this:
var sorted = animals.ToLookup(type => Regex.Match(type,
"(dog|cat|lemur)",
RegexOptions.IgnoreCase).Value);

Then to get our cats, here is the code:
sorted["cat"].ToList()