65.9K
CodeProject is changing. Read more.
Home

Using Linq with Regular Expression results

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (10 votes)

Mar 28, 2014

CPOL
viewsIcon

29951

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