Using Linq with Regular Expression results






4.85/5 (10 votes)
Want to use Linq, or Linq methods with the results from your Regex? Yes, so did I...annoying isn't it? So...a solution.
Introduction
I like regexes. I'm not that fond of the syntax, but it's a complex task and the language is understandably complex - and Expresso[^] makes it a lot easier anyway - it's free, and it examines and generates Regular expressions.
But...I also like Linq and Linq methods and the deferred execution they allow. Unfortunately, the two are not compatible: the MatchCollection class does not implement IEnumerable<T>, so you can't use Linq.
So I had a little think, and realised there was nothing stopping me from converting a MatchCollection to an IEnumerable<Match> - it's actually really, really simple: all you need is yield return
The methods
I defined two methods: one for the MatchCollection to Enumerate the Matches, the other for the Match to Enumerate the Groups, and made them simple extension methods:
public static class ExtensionMethods
{
/// <summary>
/// Returns the input typed as a generic IEnumerable of the groups
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public static IEnumerable<System.Text.RegularExpressions.Group> AsEnumerable(this System.Text.RegularExpressions.GroupCollection gc)
{
foreach (System.Text.RegularExpressions.Group g in gc)
{
yield return g;
}
}
/// <summary>
/// Returns the input typed as a generic IEnumerable of the matches
/// </summary>
/// <param name="mc"></param>
/// <returns></returns>
public static IEnumerable<System.Text.RegularExpressions.Match> AsEnumerable(this System.Text.RegularExpressions.MatchCollection mc)
{
foreach (System.Text.RegularExpressions.Match m in mc)
{
yield return m;
}
}
}
And that's all you need...
Using the code
Just include the above class anywhere in your namespace, (or in a class library file, with the appropriate using
statement) and off you go:
string input = "<Polygon>\n" +
" <Vertex x=\"9352.7606\" y=\"8250.6001\" z=\"505.3871\" />\n" +
" <Vertex x=\"9352.7573\" y=\"8250.6001\" z=\"505.3844\" />\n" +
" </Polygon>";
MatchCollection matches = Regex.Matches(input, @"(\d+)(\.\d+)?");
var x = matches.AsEnumerable().Select(m => m.Value);
var y = from match in matches.AsEnumerable()
select match.Value;
History
2014 Mar 28 First version.
2014 Mar 28 Removed unnecessary usage example.
2014 Mar28 Converted references in the text from IEnumerable to IEnumerable<T> - Thanks ProgramFOX! :O