24

A valid phone number contains:

  • Less than 9 characters
  • A "+" at the start
  • Only digits.

I'm trying to use regular expressions but I've only started using them and I'm not good at it. The code I have so far is:

static void Main(string[] args)
{
    Console.WriteLine("Enter a phone number.");
    string telNo = Console.ReadLine();

    if (Regex.Match(telNo, @"^(\+[0-9])$").Success)
        Console.WriteLine("correctly entered");

    else
        Console.WriteLine("incorrectly entered");

    Console.ReadLine();
}

But I don't know how to check the length of the string this way. Any help is appreciated.

d219
  • 2,707
  • 5
  • 31
  • 36
Adam Higgins
  • 705
  • 1
  • 10
  • 25
  • 4
    possible duplicate of [A comprehensive regex for phone number validation](http://stackoverflow.com/questions/123559/a-comprehensive-regex-for-phone-number-validation) – sab669 Apr 30 '15 at 14:21
  • 2
    You want to use your regex in server code (c#) or in java script? I'm not sure but there could be litte differences – Jacek Apr 30 '15 at 14:52
  • thanks for the help everyone, the one that worked for me in the end was @"^(\+\d[0-9]{1,8})$" – Adam Higgins Apr 30 '15 at 17:54
  • 1
    Does a valid phone number contain less than 9 characters, does this not depend on the country you are in? – JsonStatham May 11 '18 at 18:34
  • 4
    Gah. This question is horrible; it provides a definition of "valid phone number" that just straight up is not the true definition of what a valid phone number is (I don't know of a single country where a phone number including country code is less than 9 characters, actually - it's at least not true for the US or UK), but the current title gives no hint of this and the answers take the weird definition at face value. A title edit designed to anti-SEO this question and prevent Googlers from landing here seems to be in order... – Mark Amery Nov 14 '18 at 15:00
  • 1
    WARNING: Entire thread assumes US North American phone numbers. Use a library that supports international numbers. https://www.nuget.org/packages/libphonenumber-csharp – Sean Anderson Nov 25 '19 at 02:45

8 Answers8

29

Jacek's regex works fine

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Enter a phone number.");
        string telNo = Console.ReadLine();                      
        Console.WriteLine("{0}correctly entered", IsPhoneNumber(telNo) ? "" : "in");    
        Console.ReadLine(); 
    }

    public static bool IsPhoneNumber(string number)
    {
        return Regex.Match(number, @"^(\+[0-9]{9})$").Success;
    }
}
Greg
  • 1,076
  • 1
  • 9
  • 17
21

Your regex should look like this, you need information about char counter

@"^(\+[0-9]{9})$"
Jacek
  • 11,661
  • 23
  • 69
  • 123
15

DON'T USE A REGULAR EXPRESSION!!

There are too many variables for a regex to be of any use. Instead, just remove all characters from your string that are not 0-9, and then check to see if you have the correct number of digits left. Then it doesn't matter what extra stuff the user includes or doesn't include... ()x-+[] etc etc, as it just strips them all out and only counts the characters 0-9.

I've got a string extension that works great, and allows for a wide range of formats. It accepts an IsRequired parameter. So, you can validate a phone number like this:

string phone = "(999)999-9999"
bool isValidPhone = phone.ValidatePhoneNumber(true) // returns true

string phone ="1234567890"
bool isValidPhone = phone.ValidatePhoneNumber(true) // returns true

string phone = ""
bool isValidPhone = phone.ValidatePhoneNumber(false) // not required, so returns true

string phone = ""
bool isValidPhone = phone.ValidatePhoneNumber(true) // required, so returns false

string phone ="12345"
bool isValidPhone = phone.ValidatePhoneNumber(true) // returns false

string phone ="foobar"
bool isValidPhone = phone.ValidatePhoneNumber(true) // returns false

Here's the code (assumes a 10-digit American phone number. Adjust accordingly):

public static class StringExtensions
{

    /// <summary>
    /// Checks to be sure a phone number contains 10 digits as per American phone numbers.  
    /// If 'IsRequired' is true, then an empty string will return False. 
    /// If 'IsRequired' is false, then an empty string will return True.
    /// </summary>
    /// <param name="phone"></param>
    /// <param name="IsRequired"></param>
    /// <returns></returns>
    public static bool ValidatePhoneNumber(this string phone, bool IsRequired)
    {
        if (string.IsNullOrEmpty(phone) & !IsRequired)
            return true;

        if (string.IsNullOrEmpty(phone) & IsRequired)
            return false;

        var cleaned = phone.RemoveNonNumeric();
        if (IsRequired)
        {
            if (cleaned.Length == 10)
                return true;
            else
                return false;
        }
        else
        {
            if (cleaned.Length == 0)
                return true;
            else if (cleaned.Length > 0 & cleaned.Length < 10)
                return false;
            else if (cleaned.Length == 10)
                return true;
            else
                return false; // should never get here
        }
    }

    /// <summary>
    /// Removes all non numeric characters from a string
    /// </summary>
    /// <param name="phone"></param>
    /// <returns></returns>
    public static string RemoveNonNumeric(this string phone)
    {
        return Regex.Replace(phone, @"[^0-9]+", "");
    }
}
Casey Crookston
  • 13,016
  • 24
  • 107
  • 193
  • You're my hero. I like the way you handled this. –  May 03 '19 at 06:00
  • 1
    Hope it helps :) – Casey Crookston May 03 '19 at 19:33
  • 2
    Beware: this method works only for american phone numbers. In my country (Poland) we have 9-digit mobile numbers. Also, people sometimes add country code (+48 for Poland), because without it number won't work in another EU countries (well, it may if someone has this number in different country :D). – Makalele Dec 11 '19 at 11:01
  • @Makalele, yes you are correct. I mentioned in the answer that this will only work for 10 digit American phone numbers, and you will need to modify accordingly for anything else! – Casey Crookston Dec 11 '19 at 16:48
4

Expanding upon one of the answers provided above, the method I came up with to also handle a few phone number delivery styles as well as international phone number is

    internal static bool IsValidPhoneNumber(this string This)
    {
        var phoneNumber = This.Trim()
            .Replace(" ", "")
            .Replace("-", "")
            .Replace("(", "")
            .Replace(")", "");
        return Regex.Match(phoneNumber, @"^\+\d{5,15}$").Success;
    }
3

Something like this could work:

^+\d{0,9}

But I would suggest playing around with a regex tester to learn more about how regular expressions work. I still like to use them heavily myself, as I don't write regular expressions often. Here is one example but there are many more out there.

https://regex101.com/

maniak1982
  • 707
  • 2
  • 7
  • 23
2

Simple function for Valid USAPhoneNumber or not.

   /// <summary>
    /// Allows phone number of the format: NPA = [2-9][0-8][0-9] Nxx = [2-9]      [0-9][0-9] Station = [0-9][0-9][0-9][0-9]
    /// </summary>
    /// <param name="strPhone"></param>
    /// <returns></returns>
    public static bool IsValidUSPhoneNumber(string strPhone)
    {
        string regExPattern = @"^[01]?[- .]?(\([2-9]\d{2}\)|[2-9]\d{2})[- .]?\d{3}[- .]?\d{4}$";
        return MatchStringFromRegex(strPhone, regExPattern);
    }
    // Function which is used in IsValidUSPhoneNumber function
    public static bool MatchStringFromRegex(string str, string regexstr)
    {
        str = str.Trim();
        System.Text.RegularExpressions.Regex pattern = new System.Text.RegularExpressions.Regex(regexstr);
        return pattern.IsMatch(str);
    }
1

If you're looking for a country specific regex, try this expression which works for all Australian (+61-) numbers. I've put comments on how to go about varying it for other uses.

public static bool IsValidPhoneNumber(string phoneNumber)
{
    //will match +61 or +61- or 0 or nothing followed by a nine digit number
    return Regex.Match(phoneNumber, 
        @"^([\+]?61[-]?|[0])?[1-9][0-9]{8}$").Success;
    //to vary this, replace 61 with an international code of your choice 
    //or remove [\+]?61[-]? if international code isn't needed
    //{8} is the number of digits in the actual phone number less one
}
Ash
  • 5,786
  • 5
  • 22
  • 42
1

This solution validates every test criteria for validating a phone number, it also leverages from the Regex API. Criteria includes spacing, any non numeric values, area codes (which you specify), number of values (digits) the phone number should have, and also includes error messaging as well as phone number old and new state.

Here is the source code:

public class PhoneNumberValidator
{
    public string ErrorMessage { get; set; }
    public int PhoneNumberDigits { get; set; }
    public string CachedPhoneNumber { get; set; }

    private Dictionary<int, string> VaildAreaCodes()
    {
        return new Dictionary<int, string>
        {
            [3] = "0",
            [4] = "27"
        };
    }

    private bool IsInteger(string value)
    {
        return int.TryParse(value, out int result);
    }

    private string GetConsecutiveCharsInPhoneNumberStr(string phoneNumber)
    {
        switch (PhoneNumberDigits)
        {
            case 0:
            case 10:
                PhoneNumberDigits = 10;
                return phoneNumber.Substring(phoneNumber.Length - 7);

            case 11:
                return phoneNumber.Substring(phoneNumber.Length - 8);

            default:
                return string.Empty;
        }
    }

    private bool IsValidAreaCode(ref string phoneNumber, string areaCode)
    {
        if (!IsInteger(areaCode))
        {
            ErrorMessage = "Area code characters of Phone Number value should only contain integers.";
            return false;
        }

        var areaCodeLength = areaCode.Length;
        var invalidAreaCodeMessage = "Phone Number value contains invalid area code.";
        switch (areaCodeLength)
        {
            case 2:
                phoneNumber = string.Concat("0", phoneNumber);
                return true;

            case 3:
                if (!areaCode.StartsWith(VaildAreaCodes[3]))
                    ErrorMessage = invalidAreaCodeMessage;
                return string.IsNullOrWhiteSpace(ErrorMessage) ? true : false;

            case 4:
                if (areaCode.StartsWith(VaildAreaCodes[4]))
                {
                    phoneNumber = string.Concat("0", phoneNumber.Remove(0, 2)); // replace first two charaters with zero
                    return true;
                }                    
                ErrorMessage = invalidAreaCodeMessage;
                return false;                

            default:
                ErrorMessage = invalidAreaCodeMessage;
                return false;
        }
    }   

    public bool IsValidPhoneNumber(ref string phoneNumber)
    {
        CachedPhoneNumber = phoneNumber;

        if (string.IsNullOrWhiteSpace(phoneNumber))
        {
            ErrorMessage = "Phone Number value should not be equivalent to null.";
            return false;
        }

        phoneNumber = Regex.Replace(phoneNumber, " {2,}", string.Empty); // remove all whitespaces
        phoneNumber = Regex.Replace(phoneNumber, "[^0-9]", string.Empty); // remove all non numeric characters

        var lastConsecutiveCharsInPhoneNumberStr = GetConsecutiveCharsInPhoneNumberStr(phoneNumber);

        if (string.IsNullOrWhiteSpace(lastConsecutiveCharsInPhoneNumberStr))
        {
            ErrorMessage = "Phone Number value not supported.";
            return false;
        }

        if (!IsInteger(lastConsecutiveCharsInPhoneNumberStr))
        {
            ErrorMessage = "Last consecutive characters of Phone Number value should only contain integers.";
            return false;
        }

        var phoneNumberAreaCode = phoneNumber.Replace(lastConsecutiveCharsInPhoneNumberStr, "");

        if (!IsValidAreaCode(ref phoneNumber, phoneNumberAreaCode))
        {
            return false;
        }            

        if (phoneNumber.Length != PhoneNumberDigits)
        {
            ErrorMessage = string.Format("Phone Number value should contain {0} characters instead of {1} characters.", PhoneNumberDigits, phoneNumber.Length);
            return false;
        }

        return true;
    }
}

The solution is highly configurable and may be used for any digits phone number as well as area code.

TechManiac
  • 214
  • 3
  • 12