Как отформатировать строку как номер телефона в 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
Дано
Вы должны указать, является ли это только североамериканские номера или нет.
Армстронгест
ВНИМАНИЕ: Вся тема предполагает номера телефонов в Северной Америке. Используйте библиотеку, которая поддерживает международные номера. 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
Я знаю, что это просто повторение комментария выше, но этот ответ не ответил на вопрос. Как вы форматируете строку в определенный формат, в данном случае формат телефонного номера.
dyslexicanaboko
168

Я предпочитаю использовать регулярные выражения:

Regex.Replace("1112224444", @"(\d{3})(\d{3})(\d{4})", "$1-$2-$3");
Райан Даффилд
источник
4
Я полагаю, это будет работать, но формат .ToString () легче читать и должен работать лучше.
Джоэл Коухорн
14
Если я уже имею дело со строкой, как сказал плакат, отбрасывать ее назад и обратно кажется глупым.
Райан Даффилд
Может быть, это то, что мне нужно в конце концов. может справиться с расширением лучше
Брайан Г
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?
Прадип
Я также использую 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 или пробелу.
Каверман
1
Это сработало для меня после всех вышеперечисленных, которые я попробовал
Eliotjse
22

Насколько я знаю, вы не можете сделать это с помощью string.Format ... вам придется справиться с этим самостоятельно. Вы можете просто удалить все нечисловые символы, а затем сделать что-то вроде:

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

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

mattruma
источник
4
И это предполагает североамериканский номер телефона
Крис
19

Это должно работать:

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

ИЛИ в вашем случае:

String.Format("{0:###-###-####}", Convert.ToInt64("1112224444"));
Вивек Шеной
источник
3
1 небольшая проблема, если я использую 01213456789 его делает (12) 345-6789 ... любое решение ...?
Санграм Нандхиле
5
Это лучшее решение. Ведущий ноль является спорным по отношению к американским телефонным номерам, поскольку нет никаких американских кодов, которые начинаются с нуля или единицы.
JB
Небольшая проблема, если я попробовал 12345678, он форматирует (1) 234-5678 ... Но что мне нужно, это (123) 456-78. Есть ли решение для этого? Спасибо
Кавита П.
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
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
Имейте в виду, что разные страны имеют разные форматы и длины телефонных номеров, и люди не смогут их ввести.
Неме
Как бы я использовал это с 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);

Тогда ответ, который вы перечислили, должен работать в большинстве случаев.

Чтобы ответить на вопрос о расширении, вы можете удалить все, что длиннее ожидаемой длины в десять (для обычного номера телефона), и добавить это в конец, используя

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
STH
источник
Проголосовал, но ... Это ответ на vb.net и вопрос c #
вход: 1234567890 выход: (123) 456-789 не работает!
MC9000
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 в 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

Mak
источник
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;
}

Передайте свой номер телефона в виде строки 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;
}
Нил Гарсия
источник