【问题标题】:How to format a string as a telephone number in C#如何在 C# 中将字符串格式化为电话号码
【发布时间】:2010-09-16 08:30:09
【问题描述】:

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

我在想:

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

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

** 更新 **

好的。我选择了这个解决方案

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

现在,当扩展名小于 4 位时,它会变得混乱。它将从右侧填写数字。所以

1112224444 333  becomes

11-221-244 3334

有什么想法吗?

【问题讨论】:

  • 请注意,并非所有地方都有 10 位数的电话号码,或使用 111-222-4444 格式。
  • 这将失败,电话号码以 0 开头
  • 您应该指定这是否仅是北美数字。
  • 警告:整个线程假定美国北美电话号码。使用支持国际号码的库。 nuget.org/packages/libphonenumber-csharp

标签: c# string formatting phone-number


【解决方案1】:
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...");
    }

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
【解决方案2】:

这是@Jon Skeet 答案的改进版本,带有空检查并具有扩展方法。

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

【讨论】:

  • 肯定不会让它成为扩展方法。接下来,如果value 为空,为什么你永远无法到达else 块?
  • 正确,因为不需要对 else 中的值进行空检查,但还不够,如果 Substring 无法从索引中提取值,它将产生 ArgumentOutOfRangeException。
【解决方案3】:

使用字符串插值和新数组index/range

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

输出:(123) 456-7890

【讨论】:

    【解决方案4】:
     Label12.Text = Convert.ToInt64(reader[6]).ToString("(###) ###-#### ");
    

    这是我的例子!我希望可以帮助你。 问候

    【讨论】:

      【解决方案5】:
              string phoneNum;
              string phoneFormat = "0#-###-###-####";
              phoneNum = Convert.ToInt64("011234567891").ToString(phoneFormat);
      

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

        • 这对我有用,但我必须先添加检查以确保电话值不是 NULL 或空白。
        • 在我尝试了上述所有方法之后,这对我有用
        【解决方案7】:

        这是另一种方法。

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

        【讨论】:

          【解决方案8】:

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

          【讨论】:

            【解决方案9】:

            如果您正在寻找要实时转换的(美国)电话号码。我建议使用这个扩展。这种方法可以完美地工作,无需向后填写数字。 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 很好。这已得到纠正,我已将代码重构为一般用途的扩展。
            【解决方案10】:

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

            最简单的格式化方法是使用正则表达式。

            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)
            

            另一种方法是使用子字符串

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

            【讨论】:

              【解决方案11】:

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

              来自good page 的例子:

              String.Format("{0:(###) ###-####}", 8005551212);
              
                  This will output "(800) 555-1212".
              

              虽然正则表达式可能会更好,但请记住旧的编程报价:

              有些人在遇到 问题,想“我知道,我会用 常用表达。”现在他们有 两个问题。
              --Jamie Zawinski,在 comp.lang.emacs 中

              【讨论】:

              • 会发生什么,假设电话号码缺少几位数字 - 仅如“800555”?有没有办法只显示那里的内容?
              • 这是一个糟糕的实现,因为如果区号以 0105555555 或类似的开头,那么您最终会返回 (01) 555-5555 而不是 (010) 555-5555。原因是如果您将电话号码转换为数字,那么前面的零被视为没有任何意义,并且当您对其进行格式化时,第一个 0 会被丢弃。
              • @Paul 请阅读问题定义:“我有一个字符串“1112224444”,它是一个电话号码。我想在将其存储到文件之前将其格式化为 111-222-4444”。
              • 如果您的电话号码是字符串,如问题所述,这将不起作用,除非您先将其转换为数值。
              • 我知道这只是重复上面的评论,但这个答案并没有回答这个问题。如何将字符串格式化为特定格式,在本例中为电话号码格式。
              【解决方案12】:

              您可能会遇到这样的情况:用户尝试输入电话号码,在区号和主要号码块之间使用各种分隔符(例如,空格、破折号、句点等...)所以你'我想去掉所有不是数字的字符的输入,这样你就可以对你正在使用的输入进行消毒。最简单的方法是使用 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("###-###-####");
              

              【讨论】:

                【解决方案13】:

                你也可以试试这个:

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

                输出:

                【讨论】:

                • 请注意,不同国家/地区的电话号码格式和长度不同,人们无法输入。
                • 如何将它与 Html.DisplayFor(model => model.PhoneNumber) 一起使用?
                • 我使用了这个,并想出了如何在 Razor 页面显示中使用它。我把它放在页面顶部的 @functions{ } 块中。然后我摆脱了 @Html.DisplayFor 帮助程序,只引用了函数:..................@GetFormattedPhoneNumber(Model.Courses_New.CurrentContactPhone) 让我开心!
                【解决方案14】:

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

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

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

                【讨论】:

                  【解决方案15】:

                  不是要复活一个老问题,但我想如果设置稍微复杂一点,我至少可以提供一种更易于使用的方法。

                  因此,如果我们创建一个新的自定义格式化程序,我们可以使用更简单的 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- 所以你可能想让它在构造函数中使用某种可能的填充字符。

                  此外,我没有提供转义 # 符号的方法,因此如果您想将其包含在输出字符串中,您将无法按照现在的方式进行操作。

                  我更喜欢这种方法而不是正则表达式的原因是我经常要求允许用户自己指定格式,而且我解释如何使用这种格式比尝试教用户正则表达式要容易得多。

                  此外,类名有点用词不当,因为它实际上可以格式化任何字符串,只要你想保持它在相同的顺序,只是在其中注入字符。

                  【讨论】:

                    【解决方案16】:
                    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 不起作用
                    【解决方案17】:

                    在 Regex 中使用 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();
                    

                    【讨论】:

                      【解决方案18】:

                      这应该可行:

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

                      或者在你的情况下:

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

                      【讨论】:

                      • 1 个小问题,如果我使用 01213456789 它的品牌 (12) 345-6789...任何解决方案...?
                      • 这是最好的解决方案。对于美国电话号码,前导零没有实际意义,因为没有以零或一开头的美国区号。
                      • 小问题,如果我尝试 12345678,它会格式化 (1) 234-5678... 但我需要的是 (123) 456-78。有什么解决办法吗?谢谢
                      【解决方案19】:
                      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

                      【讨论】:

                        【解决方案20】:

                        试试这个

                        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;
                        

                        干杯。

                        【讨论】:

                          【解决方案21】:

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

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

                          【讨论】:

                            【解决方案22】:

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

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

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

                            【讨论】:

                            • 它假定一个北美电话号码
                            • 基于这个答案很容易构建任何解决方案。而且,这不限于特定长度。谢谢。
                            【解决方案23】:
                            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 不起作用!
                            【解决方案24】:

                            如果你能得到i["MyPhone"]作为long,你可以使用long.ToString()方法来格式化它:

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

                            请参阅 Numeric Format Strings 上的 MSDN 页面。

                            小心使用 long 而不是 int:int 可能会溢出。

                            【讨论】:

                            • 这个问题是如果数字长度大于 10 个字符(即包括扩展名)。这会导致 非常 奇怪的表示形式,其中 212-555-1212 x1234 显示为 2125551-212-1234.
                            【解决方案25】:

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

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

                            【讨论】:

                            • 我想这会起作用,但是 .ToString() 格式更容易阅读并且性能应该更好。
                            • 如果我已经在处理一个字符串,就像发帖人所说的那样,将它转换为 long 然后再返回似乎很愚蠢。
                            • 也许这就是我所需要的。可以更好地处理扩展
                            • +1 用于将号码保存为字符串(鉴于通常用于自动 SMS 系统的电话号码必须以 +44 格式存储)
                            • 我正在使用不同的格式(例如 (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");
                            【解决方案26】:

                            您需要将其分解为子字符串。虽然您可以在没有任何额外变量的情况下这样做,但它不会特别好。这是一个潜在的解决方案:

                            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 更好吗?
                            • 我也使用 String.Format - 但是您如何建议不使用 使用 String.Format 来实现结果?
                            • 我将其包装在 if (phone.Length == 10) 条件中。
                            • 加一 - 一个小点:该格式看起来不像在区号周围有括号,也许我读错了。
                            • @MarkRogers:问题是“我想格式化为 111-222-4444”——那里没有括号。
                            猜你喜欢
                            • 2011-06-12
                            • 1970-01-01
                            • 2011-07-04
                            • 2010-10-03
                            • 2011-03-06
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多