Main Contents

Linq and Regular Expressions

Schotime @ March 10, 2008

.NET

With Linq now standard in .NET 3.5, there is no reason why we shouldn’t use it. After all its full of features that can be used by any object that inherits the type IEnumberable. With such power at our fingertips, sorting, filtering, manipulation etc. etc. are available to us with fewer lines of code than previous needed.

One powerful feature of programing is Regular Expressions. These provide a concise and flexible means for identifying text of interest, such as particular characters, words, or patterns of characters. So whilst going over some old code of mine to extract data from a remote website, I decided to give the Regular Expression part of my code a face lift with Linq.

The code below is the setup code just to give some background.

String StringToMatch = "<tr class=\"ar1\"><td>456642</td>"
        + "<td class=\"left\">John</td>"
        + "<td class=\"left\">Smith</td>"
        + "<td>j.smith@email.com</td></tr>"
        + "<tr class=\"ar1\"><td>456643</td>"
        + "<td class=\"left\">Edward</td>"
        + "<td class=\"left\">Norman</td>"
        + "<td>e.norman@email.com</td></tr>";

Regex r = new Regex("<tr class=\"(?:ar1|ar2)\"><td>([0-9]+)</td>"
        + "<td class=\"left\">(.*?)</td>"
        + "<td class=\"left\">(.*?)</td>"
        + "<td>(.*?)</td></tr>");

MatchCollection matches = r.Matches(StringToMatch);

The following code is the preLinq version of the code to process the Regular Expression.

List<Profile> Profiles = new List<Profile>();

if (matches.Count > 0)
{
    foreach (Match m in matches)
    {
        Profile p = new Profile();

        p.Id = m.Groups[1].Value;
        p.Firstname = m.Groups[2].Value;
        p.Lastname = m.Groups[3].Value;
        p.Email = m.Groups[4].Value;

        Profiles.Add(p);
    }
}

As you can see above, a strongly typed List of type Profile is created. Then we loop through each match, first creating a new instance of the Profile object. Filling the object up with the results from our Regular Expression and finally adding it to the list. Whilst this code is pretty straight forward, look how easily Linq handles this scenario.

if (matches.Count > 0)
{
     List<Profile> Profiles = (from Match m in matches
                              select new Profile
                              {
                                  Id = m.Groups[1].Value,
                                  Firstname = m.Groups[2].Value,
                                  Lastname = m.Groups[3].Value,
                                  Email = m.Groups[4].Value
                              }).ToList();
}

As you can see above, we have managed to reduced the amount of statements from around 8 to 1. So what this is doing in english is creating a strongly typed List of the type Profile and using Linq to fill it. It states that for ever Match m in the list matches, create a new object Profile and auto initialise the variables with the values contained in the match. Finally we convert the IEnumberable<Profile> result to a List<Profile> by using the method ToList().

How easy was that! Now say you wanted the list of Profile’s sorted by lastname. Well you would normally have to build the list as above and then call the Sort method using a defined Comparison object. This is where Linq becomes even more powerful. Simply by adding one line to the Linq statement above, the List generated will be sorted by lastname.

if (matches.Count > 0)
{
     List<Profile> Profiles = (from Match m in matches
                       --->   orderby m.Groups[3].Value
                              select new Profile
                              {
                                  Id = m.Groups[1].Value,
                                  Firstname = m.Groups[2].Value,
                                  Lastname = m.Groups[3].Value,
                                  Email = m.Groups[4].Value
                              }).ToList();
}

Also another point to add regarding the definition of class Profile. Back in .NET 2.0 days creating a class was pretty painful. A lot of repeated code just to get and object with some variables.

public class Profile
{
    private string _id;
    private string _firstname;
    private string _lastname;
    private string _email;

    public string Id
    {
        get { return _id; }
        set { _id = value; }
    }

    public string Firstname
    {
        get { return _firstname; }
        set { _firstname = value; }
    }

    public string Lastname
    {
        get { return _lastname; }
        set { _lastname = value; }
    }

    public string Email
    {
        get { return _email; }
        set { _email = value; }
    }
}

As you can see its way to long. Lets see how post .NET 2.0 does it.

public class Profile
{
    public string Id { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string Email { get; set; }
}

Now thats what i’m talking about. Good work team. Thats how easy it should be to create a class!

Til’ Next Time, It’s Schotime Out!


book mark Linq and Regular Expressions in del.icio.us submit Linq and Regular Expressions to digg.com


5 Comments

  1. Linq and Regular Expressions - Adam Schroder March 10, 2008 @ 5:46 pm

    [...] Click here to continue reading Posted: Feb 16 2008, 11:29 AM by schotime | with no comments [...]

  2. Importing Data Files with Linq | Schotime.net March 18, 2008 @ 11:22 pm

    [...] Linq and Regular Expressions [...]

  3. Importing Data Files with Linq - Adam Schroder March 18, 2008 @ 11:24 pm

    [...] Data Files with Linq In my previous Linq post I discussed using Linq with Regular expressions and how much less code was needed. In this post [...]

  4. Elda October 28, 2008 @ 12:00 am

    People should read this.

  5. Ben December 30, 2008 @ 9:55 am

    This rocks. Plain and simple.

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


Feed
24,358 spam comments
blocked by
Akismet