RegEx: Validating Phone Numbers

I am horrible at writing regular expressions but, like any developer, when I need them I want a good one.  Today I needed one to validate North American phone numbers, that would allow for all different kinds of formatting by the users and also allow for extensions.

On the following blog post, by Chris Nanney, I finally found the perfect one: 

/\D*\(?(\d{3})?\)?\D*(\d{3})\D*(\d{4})\D*(\d{1,8})?/

I also found this site that I used to validate that it worked as I expected: http://regex101.com/

I’ve been in the position of having to take an unnormalized database that had virtually no data validation or standardization in place, and migrating it to a normalized schema. I used regex to help me through the process.

This post will deal specifically with phone numbers. The data I was importing had many problems: First, there was no standard formatting—some numbers were stored (xxx) xxx-xxxx, some xxx-xxx-xxxx, some xxx.xxx.xxxx, etc. Second, there wasn’t a separate field for extensions—they were just tacked on the end by either ext., EXT, x, Ex, or some variation. If there were only 20 numbers or so you could just fix them by hand, but you need an automated process to deal with say, 15,000.
via Cleaning Phone Numbers with Regular Expressions : Code : Chris Nanney.

C# Tips n Tricks: Simple IsHoliday Class

Today I had a need to check if the current date was a holiday. I wrote up this quick class to do the calculations. This may be a good class to add as an extension to the DateTime class as well. It is one of those nice simple classes that is always useful.

    public class Holiday
    {
        public static bool IsHoliday(DateTime date)
        {
            return
                Holiday.IsNewYearsDay(date)
             || Holiday.IsNewYearsEve(date)
             || Holiday.IsThanksgivingDay(date)
             || Holiday.IsDayAfterThanksgiving(date)
             || Holiday.IsChristmasEve(date)
             || Holiday.IsChristmasDay(date)
             || Holiday.IsFourthOfJuly(date)
             || Holiday.IsLaborDay(date)
             || Holiday.IsMemorialDay(date);
        }
        public static bool IsNewYearsDay(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 1, 1)).DayOfYear;
        }
        public static bool IsNewYearsEve(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 12, 31)).DayOfYear;
        }
        public static bool IsChristmasEve(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 12, 24)).DayOfYear;
        }
        public static bool IsChristmasDay(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 12, 25)).DayOfYear;
        }
        public static bool IsFourthOfJuly(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 7, 4)).DayOfYear;
        }
        public static bool IsLaborDay(DateTime date)
        { // First Monday in September
            DateTime laborDay = new DateTime(date.Year, 9, 1);
            DayOfWeek dayOfWeek = laborDay.DayOfWeek;
            while (dayOfWeek != DayOfWeek.Monday)
            {
                laborDay = laborDay.AddDays(1);
                dayOfWeek = laborDay.DayOfWeek;
            }
            return date.DayOfYear == laborDay.DayOfYear;
        }
        public static bool IsMemorialDay(DateTime date)
        { //Last Monday in May
            DateTime memorialDay = new DateTime(date.Year, 5, 31);
            DayOfWeek dayOfWeek = memorialDay.DayOfWeek;
            while (dayOfWeek != DayOfWeek.Monday)
            {
                memorialDay = memorialDay.AddDays(-1);
                dayOfWeek = memorialDay.DayOfWeek;
            }
            return date.DayOfYear == memorialDay.DayOfYear;
        }
        public static bool IsThanksgivingDay(DateTime date)
        {//4th Thursday in November
            var thanksgiving = (from day in Enumerable.Range(1, 30)
                                where new DateTime(date.Year, 11, day).DayOfWeek == DayOfWeek.Thursday
                                select day).ElementAt(3);
            DateTime thanksgivingDay = new DateTime(date.Year, 11, thanksgiving);
            return date.DayOfYear == thanksgivingDay.DayOfYear;
        }
        public static bool IsDayAfterThanksgiving(DateTime date)
        {//Day after Thanksgiving
            var thanksgiving = (from day in Enumerable.Range(1, 30)
                                where new DateTime(date.Year, 11, day).DayOfWeek == DayOfWeek.Thursday
                                select day).ElementAt(3);
            DateTime thanksgivingDay = new DateTime(date.Year, 11, thanksgiving + 1);
            return date.DayOfYear == thanksgivingDay.DayOfYear;
        }

        private static DateTime AdjustForWeekendHoliday(DateTime holiday)
        {
            if (holiday.DayOfWeek == DayOfWeek.Saturday)
            {
                return holiday.AddDays(-1);
            }
            else if (holiday.DayOfWeek == DayOfWeek.Sunday)
            {
                return holiday.AddDays(1);
            }
            else
            {
                return holiday;
            }
        }
    }

JavaScript Tips n Tricks: Has only digits

Sometimes it’s necessary to do validation manually in javascript.  One that I had to do recently was to do a simple check that a value only had digits in it.  It should be obvious but since I had to look it up I figure I will post it so I can reference it in the future.


var notes = $("#txtContactExt").val();
if (/\D/.test(notes))
{
validationText += "*Please use numbers only for Phone Extension.";
}

C# Tips n Tricks: ToStringOrEmpty()

Here is another one of those extension methods that I carry with me from job to job.  It’s a super simple one that just makes sense.  So many times I am working with variables that need to be displayed as empty strings when they are null.  The following code gets tiresome when generating dozens of strings in a row.

var displayString = value == null ? String.Empty : value.ToString();

Instead I added the following extension method for strings. Technically it works for any object that has ToString() implemented.

It means that I can simply show the following code which is much simpler and nicer and cleans my code up tremendously.

        public static string ToStringOrEmpty(this object value)
        {
            return ((object)value ?? String.Empty).ToString();
        }

Update: A former co-worker sent me this CodeProject Article: Chained null checks and the Maybe monad that takes this concept a bit further with a fairly complex set of extensions that allow cleaning up null checks even more.  I’ll have to dig into it deeper.

C# Tips n Tricks: Adding a "From Camel Case" string extension method

On occasion I am working with strings that are simply the enum value, such as “MyEnum.SampleEnumName”.  I want to display it as a string without the camelcase formatting “Sample Enum Name”.  To do this I added the following FromCamelCase extension method to string.

namespace CustomExtensions
{
    public static class StringExtension
    {
        public static string ToStringOrEmpty(this object value)
        {
            return string.Concat(value, "");
        }

        /// <summary>
        /// Converts a string from CamelCase to a human readable format. 
        /// Inserts spaces between upper and lower case letters. 
        /// Also strips the leading "_" character, if it exists.
        /// </summary>
        /// <param name="propertyName"></param>
        /// <returns>A human readable string.</returns>
        public static string FromCamelCase(this string propertyName)
        {
            string returnValue = null;
            returnValue = propertyName.ToStringOrEmpty();

            //Strip leading "_" character
            returnValue = Regex.Replace(returnValue, "^_", "").Trim(); 
            //Add a space between each lower case character and upper case character
            returnValue = Regex.Replace(returnValue, "([a-z])([A-Z])", "$1 $2").Trim(); 
            //Add a space between 2 upper case characters when the second one is followed by a lower space character
            returnValue = Regex.Replace(returnValue, "([A-Z])([A-Z][a-z])", "$1 $2").Trim(); 

            return returnValue;
        }
    }
}