如何在C#中将字符串格式化为电话号码


163

我有一个字符串“ 1112224444”,它是一个电话号码。在将其存储到文件中之前,我想将其格式化为111-222-4444。它位于数据记录中,我希望能够在不分配新字符的情况下执行此操作变量。

我刚在想:

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

但这似乎并不能解决问题。

**更新**

好。我去了这个解决方案

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

现在,当扩展名少于4位时,它就会混乱。它将从右边填写数字。所以

1112224444 333  becomes

11-221-244 3334

有任何想法吗?


5
请注意,并非每个地方都有10位电话号码,或使用111-222-4444格式。
Dour High Arch

这将失败,电话号码以0开头
dano

您应该指定是否仅是北美数字。
阿姆斯特朗(Armstrongest)

警告:整个线程采用美国北美电话号码。使用支持国际号码的库。nuget.org/packages/libphonenumber-csharp
肖恩·安德森

Answers:


204

请注意,此答案适用于数字数据类型(int,long)。如果您以字符串开头,则需要先将其转换为数字。另外,请考虑到您需要验证初始字符串的长度至少为10个字符。

在完整的示例页面中:

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

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

尽管正则表达式可能会更好,但是请记住旧的编程语录:

有些人遇到问题时会认为“我知道,我会使用正则表达式。” 现在他们有两个问题。
--Jamie Zawinski,在comp.lang.emacs中


如果电话号码缺少几位数字-仅是“ 800555”,会发生什么情况?有没有办法只显示那里的东西?
VoodooChild 2011年

11
这是一个不好的实现,因为如果区号以0105555555或类似的内容开头,那么您最终将获得(01)555-5555而不是(010)555-5555。原因是,如果将电话​​号码转换为数字,则前面的零将被视为任何东西,并且在格式化时,第一个0将被丢弃。
Paul Mendoza

3
@Paul请阅读问题定义:“我有一个字符串“ 1112224444”,它是电话号码。我想先将其格式化为111-222-4444,然后再将其存储在文件中。”
Sean

39
如问题所述,如果您的电话号码是字符串,则此方法将不起作用,除非您先将其转换为数字值。
贾斯汀·斯托勒

4
我知道这只是重复上面的评论,但是这个答案并没有回答问题。如何将字符串格式化为特定格式,在这种情况下为电话号码格式。
dyslexicanaboko

168

我更喜欢使用正则表达式:

Regex.Replace("1112224444", @"(\d{3})(\d{3})(\d{4})", "$1-$2-$3");

4
我想这会起作用,但是.ToString()格式更易于阅读,并且应该表现得更好。
Joel Coehoorn

14
如海报所述,如果我已经在处理一个字符串,将其抛到很长的地方然后再放回去似乎很愚蠢。
瑞安·杜菲尔德

也许这毕竟是我需要的。可能会更好地处理扩展程序
Brian G

5
+1以保持数字为字符串(假设自动SMS系统使用的电话号码通常必须以+44格式存储)
Ed James

3
我正在使用各种格式(例如(111)222-4444、111.222.4444等),但需要将它们标准化为(111)222-4444。我还想防止出现不完整的数字,并使用{n,m}表示法。(对格式表示歉意,但某些MD格式对我不起作用)。 // 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

46

您需要将其分成子字符串。尽管您可以在没有任何额外变量的情况下做到这一点,但这并不是特别好。这是一个潜在的解决方案:

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)您确定使三个子字符串比使用string.format更好吗?
Pradeep

我也使用String.Format-但是您如何建议使用String.Format 来获得结果呢?
乔恩·斯基特

2
我把它包裹起来if (phone.Length == 10)
Zack Peterson

加一-一个小问题:该格式看起来不像在区号周围带有括号,也许我读错了。
Mark Rogers 2014年

1
@MarkRogers:问题说“我想格式化为111-222-4444”-那里没有任何括号。
乔恩·斯基特

28

我建议将其作为美国电话号码的干净解决方案。

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;
}

1
这对我有用,除了我必须添加检查以确保电话的值不是NULL或首先不是空格。
Caverman

1
在我尝试了上述所有方法之后,此方法对我有效
Eliotjse

22

据我所知,您不能使用string.Format执行此操作……您必须自己处理。您可以删除所有非数字字符,然后执行以下操作:

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

这假定已经正确输入了数据,您可以使用正则表达式进行验证。


4
并且它假定了一个北美电话号码
chris

19

这应该工作:

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

或者在您的情况下:

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

3
1个小问题,如果我使用的是01213456789,它会使(12)345-6789 ...任何解决方案...?
Sangram Nandkhile 2011年

5
这是最好的解决方案。对于美国电话号码,前导零是无意义的,因为没有以零或一开头的美国区号。
JB 2012年

小问题,如果我尝试使用12345678,它会格式化(1)234-5678 ...但是我需要的是(123)456-78。有什么解决办法吗?谢谢
Kavitha P.

14

如果你能得到i["MyPhone"]long,你可以使用long.ToString()方法对其进行格式化:

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

请参阅有关数字格式字符串的MSDN页面

注意使用long而不是int:int可能会溢出。


1
问题在于,如果数字的长度大于10个字符(即包括扩展名)。这导致一个非常奇怪的表示形式,其中212-555-1212 x1234表示为2125551-212-1234.
迈克尔·布莱克本

5
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

输入:1234567890输出:123 456 78 90不起作用
MC9000 2015年

5

如果您正在寻找要实时转换的(美国)电话号码。我建议使用此扩展名。此方法完美地工作,而无需向后填充数字。该String.Format解决方案似乎向后工作。只需将此扩展名应用于您的字符串即可。

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;
}

非常适合向前运动。但是返回时,它停留在(###)的第一种格式。
Schwagmister

@Schwagmister很好。此问题已得到纠正,我已将代码重构为常规使用的扩展名。
詹姆斯·科普兰

4

您也可以尝试以下操作:

  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;
        }

输出:

在此处输入图片说明


1
请注意,不同国家/地区的电话号码格式和长度不同,因此人们将无法输入。
尼姆

我将如何与Html.DisplayFor(model => model.PhoneNumber)一起使用?
JustJohn

我使用了这个,并弄清楚了如何在Razor Page显示中使用它。我将其放在页面顶部的@functions {}块中。然后,我摆脱了@ Html.DisplayFor帮助器,而只引用了该函数:................. @GetFormattedPhoneNumber(Model.Courses_New.CurrentContactPhone)让我开心了!
JustJohn

4

您可能会遇到这样的情况:用户尝试用区号和主号码块之间的各种分隔符(例如,空格,破折号,句点等)输入电话号码,因此您需要去除所有非数字字符的输入,以便对正在使用的输入进行灭菌。最简单的方法是使用RegEx表达式。

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

然后,您列出的答案在大多数情况下应该有效。

要回答有关扩展名问题的信息,您可以删除任何超出预期长度10(对于常规电话号码)的内容,然后使用

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

在执行此操作之前,您将需要进行“ if”检查以确定输入的长度是否大于10,否则请使用:

formattedPhoneNumber = Convert.ToInt64(value).ToString("###-###-####");

3
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

投票了,但是...这是vb.net的答案,问题是c#

输入:1234567890输出:(123)456-789不起作用!
MC9000 2015年

3
        string phoneNum;
        string phoneFormat = "0#-###-###-####";
        phoneNum = Convert.ToInt64("011234567891").ToString(phoneFormat);

2

试试这个

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;

干杯。


2

在正则表达式中使用Match进行拆分,然后输出具有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();

2

以下将在不使用正则表达式的情况下工作

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

如果我们不使用long.Parse,则string.format将不起作用。


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;
}

输出将是:001-568-895623


1

请为C#使用以下链接 http://www.beansoftware.com/NET-Tutorials/format-string-phone-number.aspx

进行格式的最简单方法是使用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;
}

将您的phoneNum作为字符串2021231234传递,最多15个字符。

FormatPhoneNumber(string phoneNum)

另一种方法是使用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;
    }

0

要解决您的扩展程序问题,如何:

string formatString = "###-###-#### ####";
returnValue = Convert.ToInt64(phoneNumber)
                     .ToString(formatString.Substring(0,phoneNumber.Length+3))
                     .Trim();

0

不想复活一个老问题,但认为我可能会提供一种稍微更简单易用的方法,如果设置稍微复杂一点的话。

因此,如果我们创建新的自定义格式器,则可以使用以下更简单的格式 string.Format而无需将我们的电话号码转换为long

因此,首先让我们创建自定义格式化程序:

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;
        }
    }
}

因此,如果要使用此功能,则可以执行以下操作:

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

需要考虑的其他事项:

现在,如果您指定的格式化程序比格式化字符串的时间长,它将忽略其他#号。例如这个String.Format(new NumericStringFormatter(),"{0:###-###-####}", "12345");将导致123-45-,因此您可能希望在构造函数中使用某种可能的填充符。

另外,我也没有提供一种转义#号的方法,因此,如果您想在输出字符串中包含它,您将无法立即使用它。

我之所以喜欢这种方法而不是正则表达式,是因为我经常有一些要求,允许用户自己指定格式,并且比起教用户正则表达式,我更容易解释如何使用这种格式。

而且,类名有点用词不当,因为它实际上可以格式化任何字符串,只要您想使其保持相同的顺序并在其中插入字符即可。


0

如果您的目标编号以0开头,则可以尝试{0:(000)000-####}。


0

这是另一种方法。

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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.