188

I have a string "1112224444' it is a telephone number. I want to format as 111-222-4444 before I store it in a file. It is on a datarecord and I would prefer to be able to do this without assigning a new variable.

I was thinking:

String.Format("{0:###-###-####}", i["MyPhone"].ToString() );

but that does not seem to do the trick.

** UPDATE **

Ok. I went with this solution

Convert.ToInt64(i["Customer Phone"]).ToString("###-###-#### ####")

Now its gets messed up when the extension is less than 4 digits. It will fill in the numbers from the right. so

1112224444 333  becomes

11-221-244 3334

Any ideas?

Kara
  • 6,115
  • 16
  • 50
  • 57
Brian G
  • 53,704
  • 58
  • 125
  • 140

26 Answers26

220

Please note, this answer works with numeric data types (int, long). If you are starting with a string, you'll need to convert it to a number first. Also, please take into account that you'll need to validate that the initial string is at least 10 characters in length.

From a good page full of examples:

String.Format("{0:(###) ###-####}", 8005551212);

    This will output "(800) 555-1212".

Although a regex may work even better, keep in mind the old programming quote:

Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems.
--Jamie Zawinski, in comp.lang.emacs

Zoey M
  • 714
  • 5
  • 17
Sean
  • 4,580
  • 1
  • 19
  • 18
  • What happens, lets say if the phone number is missing few digits - like "800555" only? is there a way to display only what is present there? – VoodooChild Jan 18 '11 at 20:13
  • 11
    This is a bad implementation because if the area code starts with 0105555555 or something like that then you end up getting back (01) 555-5555 instead of (010) 555-5555. The reason being is that if you convert the phone number to a number then the zero at the front is seen as not being anything and and when you format it the first 0 gets dropped. – Paul Mendoza Mar 03 '11 at 18:13
  • 3
    @Paul Please read the problem definition: "I have a string "1112224444' it is a telephone number. I want to format as 111-222-4444 before I store it in a file". – Sean Mar 29 '11 at 16:45
  • 46
    This will not work if your phone number is a string, as the questions states, unless you convert it to a numerical value first. – JustinStolle Dec 01 '11 at 22:41
  • 4
    I know this is just repeating the comment above, but this answer didn't answer the question. How do you format a string into a specific format, in this case a telephone number format. – dyslexicanaboko Oct 03 '12 at 15:19
  • I've never heard that quote before, so i've searchead it, i'd suggest to read about it [http://regex.info/blog/2006-09-15/247] – LaXfar Oct 12 '20 at 07:24
  • How would this work if you had characters (i.e. (555) 555-ABCD) – Eitan K Mar 11 '22 at 19:05
194

I prefer to use regular expressions:

Regex.Replace("1112224444", @"(\d{3})(\d{3})(\d{4})", "$1-$2-$3");
Ryan Duffield
  • 18,497
  • 6
  • 40
  • 40
  • 4
    I suppose this would work, but the .ToString() format is easier to read and should perform better. – Joel Coehoorn Oct 09 '08 at 18:36
  • 18
    If I'm dealing with a string already, as the poster has said, casting it to a long and back again seems silly. – Ryan Duffield Oct 09 '08 at 18:39
  • Maybe this is what I need after all. may handle the extension better – Brian G Dec 30 '08 at 14:44
  • 5
    +1 for keeping the number as a string (given that often phone numbers used for automated SMS systems have to be stored in the +44 format) – Ed James Dec 18 '09 at 09:39
  • These phone numbers would format correctly with this. "7779993333", "7779990000", "0109993333", "(999) 838-2222" – Paul Mendoza Mar 03 '11 at 18:14
  • 5
    I'm working with varying formats (e.g. (111) 222-4444, 111.222.4444, etc.), but need them normalized to (111) 222-4444. I also wanted to protect against incomplete numbers and used _{n,m}_ notation. (And apologies for the formatting, but some of the MD formats aren't working for me). `// Remove non-digit characters var phoneDigits = Regex.Replace(crewMember.CellPhone, "[^\\d]", string.Empty); // Format the digits var phone = Regex.Replace(phoneDigits, @"(\d{1,3})(\d{0,3})(\d{0,4})", " ($1) $2-$3");` – Craig Boland Feb 29 '16 at 19:49
53

You'll need to break it into substrings. While you could do that without any extra variables, it wouldn't be particularly nice. Here's one potential solution:

string phone = i["MyPhone"].ToString();
string area = phone.Substring(0, 3);
string major = phone.Substring(3, 3);
string minor = phone.Substring(6);
string formatted = string.Format("{0}-{1}-{2}", area, major, minor);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Jon are you sure making three substrings is better than using string.format? – Pradeep Nov 19 '08 at 18:38
  • I use String.Format as well - but how are you suggesting to achieve the result *without* using String.Format? – Jon Skeet Nov 19 '08 at 22:35
  • 2
    I wrapped that in an `if (phone.Length == 10)` condition. – Zack Peterson Mar 31 '11 at 16:32
  • Plus One - One small point: that format doesn't look like it has parenthesis around the area code, maybe I'm reading it wrong. – Mark Rogers Nov 24 '14 at 16:30
  • 3
    @MarkRogers: The question says "I want to format as 111-222-4444" - there aren't any parentheses there. – Jon Skeet Nov 24 '14 at 16:33
  • The answer with more point doesn't work for me, I don't want regular expression but this work flawless. This is just missing some null checks but regarding on the OP question this answer is ok! – revobtz Jun 07 '21 at 17:39
  • Here an improved and extension method of @JonSkeet answer public static string ToTelephoneNumberFormat(this string value, string format = "({0}) {1}-{2}") { if(string.IsNullOrWhiteSpace(value)) { return value; } else { string area = value?.Substring(0, 3) ?? ""; string major = value?.Substring(3, 3) ?? ""; string minor = value?.Substring(6) ?? ""; return string.Format(format, area, major, minor); } } – revobtz Jun 07 '21 at 17:40
  • 1
    @revobtz: I suggest you add a new answer if you believe you have a better one. – Jon Skeet Jun 07 '21 at 18:48
  • @JonSkeet added an answer derived from your answer with some null checks. – revobtz Jun 07 '21 at 20:32
  • In my case, it can't fail for invalid strings. This throws `ArgumentOutOfRangeException`s. – HappyNomad Jul 23 '21 at 14:39
  • @HappyNomad: I suggest you ask a new question with more details then - or just do appropriate validation beforehand and return whatever you want to return for an invalid phone number. – Jon Skeet Jul 23 '21 at 14:49
40

I suggest this as a clean solution for US numbers.

public static string PhoneNumber(string value)
{ 
    if (string.IsNullOrEmpty(value)) return string.Empty;
    value = new System.Text.RegularExpressions.Regex(@"\D")
        .Replace(value, string.Empty);
    value = value.TrimStart('1');
    if (value.Length == 7)
        return Convert.ToInt64(value).ToString("###-####");
    if (value.Length == 10)
        return Convert.ToInt64(value).ToString("###-###-####");
    if (value.Length > 10)
        return Convert.ToInt64(value)
            .ToString("###-###-#### " + new String('#', (value.Length - 10)));
    return value;
}
Jerry Nixon
  • 31,313
  • 14
  • 117
  • 233
28

As far as I know you can't do this with string.Format ... you would have to handle this yourself. You could just strip out all non-numeric characters and then do something like:

string.Format("({0}) {1}-{2}",
     phoneNumber.Substring(0, 3),
     phoneNumber.Substring(3, 3),
     phoneNumber.Substring(6));

This assumes the data has been entered correctly, which you could use regular expressions to validate.

mattruma
  • 16,589
  • 32
  • 107
  • 171
20

This should work:

String.Format("{0:(###)###-####}", Convert.ToInt64("1112224444"));

OR in your case:

String.Format("{0:###-###-####}", Convert.ToInt64("1112224444"));
Sathyajith Bhat
  • 21,321
  • 22
  • 95
  • 134
Vivek Shenoy
  • 201
  • 2
  • 2
  • 3
    1 small problem if i am using 01213456789 its makes (12) 345-6789...any solution...? – Sangram Nandkhile Jun 08 '11 at 12:06
  • 5
    This is the best solution. The leading zero is moot with regard to American phone numbers as there are no American area codes that begin with zero or one. – J.B. Jun 10 '12 at 00:54
  • Small issue if i tried 12345678 it formats (1) 234-5678... But what i need is (123) 456-78. Is there any solution for this? Thanks – Kavitha P. Aug 09 '17 at 09:14
14

If you can get i["MyPhone"] as a long, you can use the long.ToString() method to format it:

Convert.ToLong(i["MyPhone"]).ToString("###-###-####");

See the MSDN page on Numeric Format Strings.

Be careful to use long rather than int: int could overflow.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • 1
    The issue with this is if the number is >10 characters long (i.e. includes an extension). This results in a *very* odd representation where 212-555-1212 x1234 comes out as `2125551-212-1234.` – Michael Blackburn Jan 08 '16 at 15:15
6
static string FormatPhoneNumber( string phoneNumber ) {

   if ( String.IsNullOrEmpty(phoneNumber) )
      return phoneNumber;

   Regex phoneParser = null;
   string format     = "";

   switch( phoneNumber.Length ) {

      case 5 :
         phoneParser = new Regex(@"(\d{3})(\d{2})");
         format      = "$1 $2";
       break;

      case 6 :
         phoneParser = new Regex(@"(\d{2})(\d{2})(\d{2})");
         format      = "$1 $2 $3";
       break;

      case 7 :
         phoneParser = new Regex(@"(\d{3})(\d{2})(\d{2})");
         format      = "$1 $2 $3";
       break;

      case 8 :
         phoneParser = new Regex(@"(\d{4})(\d{2})(\d{2})");
         format      = "$1 $2 $3";
       break;

      case 9 :
         phoneParser = new Regex(@"(\d{4})(\d{3})(\d{2})(\d{2})");
         format      = "$1 $2 $3 $4";
       break;

      case 10 :
         phoneParser = new Regex(@"(\d{3})(\d{3})(\d{2})(\d{2})");
         format      = "$1 $2 $3 $4";
       break;

      case 11 :
         phoneParser = new Regex(@"(\d{4})(\d{3})(\d{2})(\d{2})");
         format      = "$1 $2 $3 $4";
       break;

      default:
        return phoneNumber;

   }//switch

   return phoneParser.Replace( phoneNumber, format );

}//FormatPhoneNumber

    enter code here
underscore
  • 752
  • 12
  • 9
5

If your looking for a (US) phone number to be converted in real time. I suggest using this extension. This method works perfectly without filling in the numbers backwards. The String.Format solution appears to work backwards. Just apply this extension to your string.

public static string PhoneNumberFormatter(this string value)
{
    value = new Regex(@"\D").Replace(value, string.Empty);
    value = value.TrimStart('1');

    if (value.Length == 0)
        value = string.Empty;
    else if (value.Length < 3)
        value = string.Format("({0})", value.Substring(0, value.Length));
    else if (value.Length < 7)
        value = string.Format("({0}) {1}", value.Substring(0, 3), value.Substring(3, value.Length - 3));
    else if (value.Length < 11)
        value = string.Format("({0}) {1}-{2}", value.Substring(0, 3), value.Substring(3, 3), value.Substring(6));
    else if (value.Length > 10)
    {
        value = value.Remove(value.Length - 1, 1);
        value = string.Format("({0}) {1}-{2}", value.Substring(0, 3), value.Substring(3, 3), value.Substring(6));
    }
    return value;
}
  • Works perfect for forward movement. But when coming back, it get's stuck at the first format of (###). –  Jun 28 '18 at 21:51
  • @Schwagmister Good catch. This has been corrected and I have refactored code to an extension for general use. – James Copeland Oct 07 '18 at 04:48
5

You can also try this:

  public string GetFormattedPhoneNumber(string phone)
        {
            if (phone != null && phone.Trim().Length == 10)
                return string.Format("({0}) {1}-{2}", phone.Substring(0, 3), phone.Substring(3, 3), phone.Substring(6, 4));
                return phone;
        }

Output:

enter image description here

Mohammad Atiour Islam
  • 5,380
  • 3
  • 43
  • 48
  • 1
    Be aware that different countries have different formats and lengths of phone numbers and people won't be able to enter them. – Neme Aug 23 '17 at 15:04
  • How would I use this with Html.DisplayFor(model => model.PhoneNumber) ? – JustJohn Jul 19 '19 at 22:44
  • I used this one and figured out how to use it in Razor Page display. I put it in a @functions{ } block at the top of the page. Then I got rid of the @Html.DisplayFor helper and just referenced the function: ................. @GetFormattedPhoneNumber(Model.Courses_New.CurrentContactPhone) Made my day! – JustJohn Jul 20 '19 at 03:10
5

You may get find yourself in the situation where you have users trying to enter phone numbers with all sorts of separators between area code and the main number block (e.g., spaces, dashes, periods, ect...) So you'll want to strip the input of all characters that are not numbers so you can sterilize the input you are working with. The easiest way to do this is with a RegEx expression.

string formattedPhoneNumber = new System.Text.RegularExpressions.Regex(@"\D")
    .Replace(originalPhoneNumber, string.Empty);

Then the answer you have listed should work in most cases.

To answer what you have about your extension issue, you can strip anything that is longer than the expected length of ten (for a regular phone number) and add that to the end using

formattedPhoneNumber = Convert.ToInt64(formattedPhoneNumber)
     .ToString("###-###-#### " + new String('#', (value.Length - 10)));

You will want to do an 'if' check to determine if the length of your input is greater than 10 before doing this, if not, just use:

formattedPhoneNumber = Convert.ToInt64(value).ToString("###-###-####");
Victor Johnson
  • 111
  • 1
  • 4
4
Function FormatPhoneNumber(ByVal myNumber As String)
    Dim mynewNumber As String
    mynewNumber = ""
    myNumber = myNumber.Replace("(", "").Replace(")", "").Replace("-", "")
    If myNumber.Length < 10 Then
        mynewNumber = myNumber
    ElseIf myNumber.Length = 10 Then
        mynewNumber = "(" & myNumber.Substring(0, 3) & ") " &
                myNumber.Substring(3, 3) & "-" & myNumber.Substring(6, 3)
    ElseIf myNumber.Length > 10 Then
        mynewNumber = "(" & myNumber.Substring(0, 3) & ") " &
                myNumber.Substring(3, 3) & "-" & myNumber.Substring(6, 3) & " " &
                myNumber.Substring(10)
    End If
    Return mynewNumber
End Function
sth
  • 222,467
  • 53
  • 283
  • 367
4
        string phoneNum;
        string phoneFormat = "0#-###-###-####";
        phoneNum = Convert.ToInt64("011234567891").ToString(phoneFormat);
4

using string interpolation and the new array index/range

var p = "1234567890";
var formatted = $"({p[0..3]}) {p[3..6]}-{p[6..10]}"

Output: (123) 456-7890

3

Try this

string result;
if ( (!string.IsNullOrEmpty(phoneNumber)) && (phoneNumber.Length >= 10 ) )
    result = string.Format("{0:(###)###-"+new string('#',phoneNumber.Length-6)+"}",
    Convert.ToInt64(phoneNumber)
    );
else
    result = phoneNumber;
return result;

Cheers.

2

Use Match in Regex to split, then output formatted string with match.groups

Regex regex = new Regex(@"(?<first3chr>\d{3})(?<next3chr>\d{3})(?<next4chr>\d{4})");
Match match = regex.Match(phone);
if (match.Success) return "(" + match.Groups["first3chr"].ToString() + ")" + " " + 
  match.Groups["next3chr"].ToString() + "-" + match.Groups["next4chr"].ToString();
Sathyajith Bhat
  • 21,321
  • 22
  • 95
  • 134
2

The following will work with out use of regular expression

string primaryContactNumber = !string.IsNullOrEmpty(formData.Profile.Phone) ? String.Format("{0:###-###-####}", long.Parse(formData.Profile.Phone)) : "";

If we dont use long.Parse , the string.format will not work.

Rama Krshna Ila
  • 486
  • 3
  • 11
1
public string phoneformat(string phnumber)
{
String phone=phnumber;
string countrycode = phone.Substring(0, 3); 
string Areacode = phone.Substring(3, 3); 
string number = phone.Substring(6,phone.Length); 

phnumber="("+countrycode+")" +Areacode+"-" +number ;

return phnumber;
}

Output will be :001-568-895623

Sathyajith Bhat
  • 21,321
  • 22
  • 95
  • 134
Mak
  • 11
  • 1
1

Please use the following link for C# http://www.beansoftware.com/NET-Tutorials/format-string-phone-number.aspx

The easiest way to do format is using Regex.

private string FormatPhoneNumber(string phoneNum)
{
  string phoneFormat = "(###) ###-#### x####";

  Regex regexObj = new Regex(@"[^\d]");
  phoneNum = regexObj.Replace(phoneNum, "");
  if (phoneNum.Length > 0)
  {
    phoneNum = Convert.ToInt64(phoneNum).ToString(phoneFormat);
  }
  return phoneNum;
}

Pass your phoneNum as string 2021231234 up to 15 char.

FormatPhoneNumber(string phoneNum)

Another approach would be to use Substring

private string PhoneFormat(string phoneNum)
    {
      int max = 15, min = 10;
      string areaCode = phoneNum.Substring(0, 3);
      string mid = phoneNum.Substring(3, 3);
      string lastFour = phoneNum.Substring(6, 4);
      string extension = phoneNum.Substring(10, phoneNum.Length - min);
      if (phoneNum.Length == min)
      {
        return $"({areaCode}) {mid}-{lastFour}";
      }
      else if (phoneNum.Length > min && phoneNum.Length <= max)
      {
        return $"({areaCode}) {mid}-{lastFour} x{extension}";
      }
      return phoneNum;
    }
1

You can try {0: (000) 000-####} if your target number starts with 0.

Alice Guo
  • 35
  • 7
1

Here is another way of doing it.

public string formatPhoneNumber(string _phoneNum)
{
    string phoneNum = _phoneNum;
    if (phoneNum == null)
        phoneNum = "";
    phoneNum = phoneNum.PadRight(10 - phoneNum.Length);
    phoneNum = phoneNum.Insert(0, "(").Insert(4,") ").Insert(9,"-");
    return phoneNum;
}
0

Not to resurrect an old question but figured I might offer at least a slightly easier to use method, if a little more complicated of a setup.

So if we create a new custom formatter we can use the simpler formatting of string.Format without having to convert our phone number to a long

So first lets create the custom formatter:

using System;
using System.Globalization;
using System.Text;

namespace System
{
    /// <summary>
    ///     A formatter that will apply a format to a string of numeric values.
    /// </summary>
    /// <example>
    ///     The following example converts a string of numbers and inserts dashes between them.
    ///     <code>
    /// public class Example
    /// {
    ///      public static void Main()
    ///      {          
    ///          string stringValue = "123456789";
    ///  
    ///          Console.WriteLine(String.Format(new NumericStringFormatter(),
    ///                                          "{0} (formatted: {0:###-##-####})",stringValue));
    ///      }
    ///  }
    ///  //  The example displays the following output:
    ///  //      123456789 (formatted: 123-45-6789)
    ///  </code>
    /// </example>
    public class NumericStringFormatter : IFormatProvider, ICustomFormatter
    {
        /// <summary>
        ///     Converts the value of a specified object to an equivalent string representation using specified format and
        ///     culture-specific formatting information.
        /// </summary>
        /// <param name="format">A format string containing formatting specifications.</param>
        /// <param name="arg">An object to format.</param>
        /// <param name="formatProvider">An object that supplies format information about the current instance.</param>
        /// <returns>
        ///     The string representation of the value of <paramref name="arg" />, formatted as specified by
        ///     <paramref name="format" /> and <paramref name="formatProvider" />.
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            var strArg = arg as string;

            //  If the arg is not a string then determine if it can be handled by another formatter
            if (strArg == null)
            {
                try
                {
                    return HandleOtherFormats(format, arg);
                }
                catch (FormatException e)
                {
                    throw new FormatException(string.Format("The format of '{0}' is invalid.", format), e);
                }
            }

            // If the format is not set then determine if it can be handled by another formatter
            if (string.IsNullOrEmpty(format))
            {
                try
                {
                    return HandleOtherFormats(format, arg);
                }
                catch (FormatException e)
                {
                    throw new FormatException(string.Format("The format of '{0}' is invalid.", format), e);
                }
            }
            var sb = new StringBuilder();
            var i = 0;

            foreach (var c in format)
            {
                if (c == '#')
                {
                    if (i < strArg.Length)
                    {
                        sb.Append(strArg[i]);
                    }
                    i++;
                }
                else
                {
                    sb.Append(c);
                }
            }

            return sb.ToString();
        }

        /// <summary>
        ///     Returns an object that provides formatting services for the specified type.
        /// </summary>
        /// <param name="formatType">An object that specifies the type of format object to return.</param>
        /// <returns>
        ///     An instance of the object specified by <paramref name="formatType" />, if the
        ///     <see cref="T:System.IFormatProvider" /> implementation can supply that type of object; otherwise, null.
        /// </returns>
        public object GetFormat(Type formatType)
        {
            // Determine whether custom formatting object is requested. 
            return formatType == typeof(ICustomFormatter) ? this : null;
        }

        private string HandleOtherFormats(string format, object arg)
        {
            if (arg is IFormattable)
                return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
            else if (arg != null)
                return arg.ToString();
            else
                return string.Empty;
        }
    }
}

So then if you want to use this you would do something this:

String.Format(new NumericStringFormatter(),"{0:###-###-####}", i["MyPhone"].ToString());

Some other things to think about:

Right now if you specified a longer formatter than you did a string to format it will just ignore the additional # signs. For example this String.Format(new NumericStringFormatter(),"{0:###-###-####}", "12345"); would result in 123-45- so you might want to have it take some kind of possible filler character in the constructor.

Also I didn't provide a way to escape a # sign so if you wanted to include that in your output string you wouldn't be able to the way it is right now.

The reason I prefer this method over Regex is I often have requirements to allow users to specify the format themselves and it is considerably easier for me to explain how to use this format than trying to teach a user regex.

Also the class name is a bit of misnomer since it actually works to format any string as long as you want to keep it in the same order and just inject characters inside of it.

Kent Cooper
  • 4,319
  • 3
  • 19
  • 23
0

To take care of your extension issue, how about:

string formatString = "###-###-#### ####";
returnValue = Convert.ToInt64(phoneNumber)
                     .ToString(formatString.Substring(0,phoneNumber.Length+3))
                     .Trim();
Larry Smithmier
  • 2,711
  • 2
  • 23
  • 30
0
 Label12.Text = Convert.ToInt64(reader[6]).ToString("(###) ###-#### ");

This is my example! I hope can help you with this. regards

Steffen Moritz
  • 7,277
  • 11
  • 36
  • 55
Leoabarca
  • 71
  • 1
  • 1
0
static void Main(string[] args)
    {
        Regex phonenumber = new(@"([0-9]{11})$");
        Console.WriteLine("Enter a Number: ");
        var number = Console.ReadLine();
        if(number.Length == 11)
        {
            if (phonenumber.IsMatch(number))
            {
                Console.WriteLine("Your Number is: "+number);
            }
            else
                Console.WriteLine("Nooob...");
        }
        else
            Console.WriteLine("Nooob...");
    }
KuroCoder
  • 5
  • 1
  • 3
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-ask). – Community Sep 19 '21 at 13:39
-1

Here is an improved version of @Jon Skeet answer with null checks and has a extension method.

public static string ToTelephoneNumberFormat(this string value, string format = "({0}) {1}-{2}") {
  if (string.IsNullOrWhiteSpace(value)) 
  {
    return value;
  } 
  else 
  {
    string area = value.Substring(0, 3) ?? "";
    string major = value.Substring(3, 3) ?? "";
    string minor = value.Substring(6) ?? "";
    return string.Format(format, area, major, minor);
  }
}
revobtz
  • 606
  • 10
  • 12
  • I *definitely* wouldn't make it an extension method. Next, why do you still have null checks for the `else` block when you'll never get there if `value` is null? – Jon Skeet Jun 07 '21 at 21:37
  • True for no need of null check for value in else but not enough, if Substring can't pull value from index it will produce ArgumentOutOfRangeException. – revobtz Jun 07 '21 at 22:04