Як відформатувати рядок як номер телефону в 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
Зауважте, що не скрізь є десятизначні телефонні номери або використовується формат 111-222-4444.
Dour High Arch

Це буде завершуватися телефонні номери , що починаються з 0
Дано

Ви повинні вказати, чи це лише північноамериканські цифри чи ні.
Армстронджест

ПОПЕРЕДЖЕННЯ: Ціла нитка передбачає американські номери телефонів у Північній Америці. Використовуйте бібліотеку, яка підтримує міжнародні номери. nuget.org/packages/libphonenumber-csharp
Шон Андерсон

Відповіді:


204

Зауважте, ця відповідь працює з числовими типами даних (int, long). Якщо ви починаєте з рядка, вам потрібно спочатку перетворити його в число. Також врахуйте, що вам потрібно підтвердити, що початковий рядок має довжину не менше 10 символів.

З гарної сторінки, наповненої прикладами:

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

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

Хоча регулярний вираз може працювати ще краще, пам’ятайте про стару цитату програмування:

Деякі люди, стикаючись з проблемою, думають: «Я знаю, я буду використовувати регулярні вирази». Зараз у них дві проблеми.
- Джеймі Завінський, в comp.lang.emacs


Що станеться, скажімо, якщо в номері телефону не вистачає кількох цифр - наприклад, "800555"? чи є спосіб відобразити лише те, що там присутнє?
VoodooChild

11
Це погана реалізація, оскільки якщо код області починається з 0105555555 або щось подібне, тоді ви в кінцевому підсумку отримуєте назад (01) 555-5555 замість (010) 555-5555. Причина полягає в тому, що якщо ви перетворюєте номер телефону в число, то нуль на передній частині вважається таким, що він нічого не становить, і коли ви форматуєте його, перший 0 падає.
Пол Мендоса

3
@Paul Будь ласка, прочитайте визначення проблеми: "У мене є рядок" 1112224444 ", це номер телефону. Я хочу сформулювати як 111-222-4444, перш ніж зберігати його у файлі ".
Шон

39
Це не спрацює, якщо ваш номер телефону є рядковим, як зазначено в запитаннях, якщо спочатку ви не перетворите його на числове значення.
JustinStolle

4
Я знаю, що це лише повторення коментаря вище, але ця відповідь не відповіла на питання. Як відформатувати рядок у певний формат, у цьому випадку - номер телефону.
dislexicanaboko

168

Я вважаю за краще використовувати регулярні вирази:

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

4
Я припускаю, що це спрацює, але формат .ToString () читається простіше і повинен працювати краще.
Джоель Куехорн

14
Якщо я вже маю справу зі струною, як сказав плакат, кидати її в довгу і назад знову здається дурною.
Райан Даффілд

Можливо, саме це мені і потрібно. може краще впоратися з розширенням
Брайан G

5
+1 для збереження номера як рядка (враховуючи, що часто телефонні номери, які використовуються для автоматизованих SMS-систем, повинні зберігатися у форматі +44)
Ед Джеймс,

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");
Крейг Боланд

47

Вам потрібно буде розбити його на підрядки. Хоча ви могли б зробити це без зайвих змінних, це було б не особливо приємно. Ось одне потенційне рішення:

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

Джон, ти впевнений, що зробити три підрядки краще, ніж використовувати string.format?
Pradeep

Я також використовую String.Format - але як ви пропонуєте досягти результату, не використовуючи String.Format?
Джон Скіт

2
Я завершив це в if (phone.Length == 10)стані.
Зак Петерсон

Плюс один - Один невеликий момент: цей формат не виглядає так, що він має круглі дужки навколо коду міста, можливо я читаю його неправильно.
Марк Роджерс

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 або Whitespace.
Каверман

1
Це спрацювало для мене після всіх перерахованих вище я спробував
Eliotjse

22

Наскільки я знаю, ви не можете цього зробити з string.Format ... вам доведеться впоратися з цим самостійно. Ви можете просто викреслити всі нечислові символи, а потім зробити щось на кшталт:

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

Це передбачає, що дані були введені правильно, і ви можете використовувати регулярні вирази для перевірки.


4
І він приймає північноамериканський номер телефону
Крісу

19

Це має працювати:

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

АБО у вашому випадку:

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

3
1 невелика проблема, якщо я використовую 01213456789 виробляє (12) 345-6789 ... будь-яке рішення ...?
Sangram Nandkhile

5
Це найкраще рішення. Провідний нуль є суперечливим щодо американських телефонних номерів, оскільки немає американських кодів місцевості, які починаються з нуля або одного.
JB

Невелике питання, якщо я спробував 12345678, це формати (1) 234-5678 ... Але що мені потрібно, це (123) 456-78. Чи є для цього рішення? Спасибі
Kavitha P.

14

Якщо ви можете отримати i["MyPhone"]як a long, ви можете скористатися long.ToString()методом для його форматування:

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

Див. Сторінку MSDN на рядках числового формату .

Будьте обережні, використовуйте довгі, а не 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

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 Хороший улов. Це було виправлено, і я відновив код до розширення для загального користування.
Джеймс Коупленд

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
Пам’ятайте, що різні країни мають різні формати та довжину номерів телефонів, і люди не зможуть вводити їх.
Neme

Як я можу використовувати це з Html.DisplayFor (model => model.PhoneNumber)?
JustJohn

Я скористався цим і придумав, як його використовувати на дисплеї сторінки Razor Я розміщую його в блоці @functions {} вгорі сторінки. Тоді я позбувся помічника @ Html.DisplayFor і просто вказав на функцію: ................. @GetFormattedPhoneNumber (Model.Courses_New.CurrentContactPhone) Зробив мій день!
JustJohn

4

Ви можете опинитися в ситуації, коли у вас є користувачі, які намагаються вводити телефонні номери з усілякими роздільниками між кодом міста та основним блоком номера (наприклад, пробілами, тире, періодами тощо). Тому вам захочеться зніміть введення всіх символів, які не є цифрами, щоб ви могли стерилізувати вхід, з яким працюєте. Найпростіший спосіб зробити це з виразом RegEx.

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

Тоді відповідь, яку ви перерахували, має працювати в більшості випадків.

Щоб відповісти, що у вас є у питанні про розширення, ви можете зняти все, що перевищує очікувану довжину десяти (для звичайного номера телефону) та додати це до кінця, використовуючи

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

Ви хочете зробити прапорець "якщо", щоб визначити, чи довжина вашого вводу перевищує 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


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 у Regex, щоб розділити, а потім вивести відформатований рядок з 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;
}

Передайте свій телефонNum як рядок 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-, тому ви, можливо, захочете, щоб він взяв якийсь можливий характер наповнювача в конструкторі.

Крім того, я не запропонував спосіб уникнути знака #, тому якби ви хотіли включити це у свій вихідний рядок, ви б не змогли так, як зараз.

Причиною, що я віддаю перевагу цьому методу над Regex, є те, що я часто маю вимоги, щоб дозволити користувачам самостійно визначати формат, і мені набагато простіше пояснити, як користуватися цим форматом, ніж намагатися навчити користувача регексу.

Також ім'я класу є дещо помилковим, оскільки воно фактично працює для форматування будь-якого рядка до тих пір, поки ви хочете зберегти його в тому ж порядку і просто вставити символи всередину нього.


0

Ви можете спробувати {0: (000) 000 - ####}, якщо ваш цільовий номер починається з 0.


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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.