Como formatar uma seqüência de caracteres como um número de telefone em C #

163

Eu tenho uma sequência "1112224444 ', é um número de telefone. Quero formatar como 111-222-4444 antes de armazená-la em um arquivo. Está em um registro de dados e eu preferiria fazer isso sem atribuir um novo variável.

Eu estava pensando:

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

mas isso não parece funcionar.

** ATUALIZAÇÃO **

Está bem. Eu fui com esta solução

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

Agora, é uma bagunça quando a extensão tem menos de 4 dígitos. Ele preencherá os números à direita. tão

1112224444 333  becomes

11-221-244 3334

Alguma ideia?

Brian G
fonte
5
Esteja ciente de que nem todo lugar tem números de telefone de 10 dígitos ou usa o formato 111-222-4444.
Dour High Arch
Isso falhará com números de telefone começando com 0
dano
Você deve especificar se esses números são norte-americanos apenas ou não.
Armstrongest
AVISO: O segmento inteiro assume os números de telefone norte-americanos dos EUA. Use uma biblioteca que suporte números internacionais. nuget.org/packages/libphonenumber-csharp
Sean Anderson

Respostas:

204

Observe que esta resposta funciona com tipos de dados numéricos (int, long). Se você estiver começando com uma sequência, precisará convertê-la em um número primeiro. Além disso, leve em consideração que você precisará validar se a sequência inicial tem pelo menos 10 caracteres.

Em uma boa página cheia de exemplos:

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

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

Embora uma regex possa funcionar ainda melhor, lembre-se da citação de programação antiga:

Algumas pessoas, quando confrontadas com um problema, pensam: "Eu sei, usarei expressões regulares". Agora eles tem dois problemas.
--Jamie Zawinski, em comp.lang.emacs

Sean
fonte
O que acontece, digamos se o número de telefone está faltando alguns dígitos - como apenas "800555"? existe uma maneira de exibir apenas o que está presente lá?
precisa saber é o seguinte
11
Esta é uma implementação ruim porque se o código de área começa com 0105555555 ou algo parecido, você acaba retornando (01) 555-5555 em vez de (010) 555-5555. A razão é que, se você converter o número de telefone em um número, o zero na frente é visto como não sendo nada e, quando você o formata, o primeiro 0 é descartado.
Paul Mendoza
3
@ Paul Por favor, leia a definição do problema: "Eu tenho uma string" 1112224444 'é um número de telefone. Quero formatar como 111-222-4444 antes de armazená-lo em um arquivo ".
Sean
39
Isso não funcionará se o seu número de telefone for uma sequência, conforme as perguntas, a menos que você o converta primeiro em um valor numérico.
perfil completo de JustinStolle
4
Eu sei que isso está apenas repetindo o comentário acima, mas esta resposta não respondeu à pergunta. Como você formata uma string em um formato específico, neste caso, um formato de número de telefone.
Dislexicanaboko
168

Eu prefiro usar expressões regulares:

Regex.Replace("1112224444", @"(\d{3})(\d{3})(\d{4})", "$1-$2-$3");
Ryan Duffield
fonte
4
Suponho que isso funcionaria, mas o formato .ToString () é mais fácil de ler e deve ter um desempenho melhor.
Joel Coehoorn
14
Se eu já estou lidando com uma corda, como o pôster já disse, lançá-la para uma longa e para trás parece boba.
Ryan Duffield
Talvez seja isso que eu preciso, afinal. pode lidar com a extensão melhor
Brian G
5
+1 para manter o número como uma string (dado que muitas vezes números de telefone utilizados para sistemas automatizados de SMS têm de ser armazenados no formato +44)
Ed James
3
Estou trabalhando com formatos variados (por exemplo, (111) 222-4444, 111.222.4444 etc.), mas preciso deles normalizados para (111) 222-4444. Eu também queria me proteger contra números incompletos e usei a notação {n, m} . (E desculpas pela formatação, mas alguns dos formatos MD não estão funcionando para mim). // 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

Você precisará dividi-lo em substrings. Embora você possa fazer isso sem nenhuma variável extra, isso não seria particularmente agradável. Aqui está uma solução em potencial:

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
fonte
Jon, você tem certeza de que fazer três substrings é melhor do que usar string.format?
Pradeep
Eu uso String.Format também - mas como você está sugerindo alcançar o resultado sem usar String.Format?
Jon Skeet
2
Eu envolvi isso em uma if (phone.Length == 10)condição.
Zack Peterson
Mais um - um pequeno ponto: esse formato não parece estar entre parênteses ao redor do código de área, talvez eu esteja lendo errado.
Mark Rogers
1
@ MarkRogers: A pergunta diz "Quero formatar como 111-222-4444" - não há parênteses lá.
Jon Skeet
28

Sugiro isso como uma solução limpa para os números dos EUA.

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
fonte
1
Isso funcionou para mim, com a exceção de que eu tinha que adicionar uma verificação para garantir que o valor do telefone não fosse NULL ou Whitespace primeiro.
Caverman 04/11/19
1
Isso funcionou para mim depois de tudo as que estão acima Eu tentei
Eliotjse
22

Tanto quanto eu sei que você não pode fazer isso com string.Format ... você teria que lidar com isso sozinho. Você pode simplesmente remover todos os caracteres não numéricos e, em seguida, fazer algo como:

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

Isso pressupõe que os dados foram inseridos corretamente, que você pode usar expressões regulares para validar.

mattruma
fonte
4
E assume um número de telefone norte-americano
chris
19

Isso deve funcionar:

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

OU no seu caso:

String.Format("{0:###-###-####}", Convert.ToInt64("1112224444"));
Vivek Shenoy
fonte
3
1 pequeno problema se estou usando 01213456789 suas marcas (12) 345-6789 ... qualquer solução ...?
Sangram Nandkhile
5
essa é a melhor solução. O zero à esquerda é discutível em relação aos números de telefone americanos, pois não há códigos de área americanos que começam com zero ou um.
JB
Pequeno problema, se eu tentei 12345678, formata (1) 234-5678 ... Mas o que eu preciso é (123) 456-78. Existe alguma solução para isso? Graças
Kavitha P.
14

Se você pode obter i["MyPhone"]como a long, pode usar o long.ToString()método para formatá-lo:

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

Consulte a página MSDN em seqüências de formato numérico .

Tenha cuidado ao usar long em vez de int: int pode estourar.

Joel Coehoorn
fonte
1
O problema é se o número tiver mais de 10 caracteres (isto é, inclui uma extensão). Isso resulta em uma muito representação ímpar onde 212-555-1212 x1234 sai como2125551-212-1234.
Michael Blackburn
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
sublinhado
fonte
entrada: 1234567890 saída: 123 456 78 90 não funciona
MC9000 11/15
5

Se você está procurando um número de telefone (EUA) para ser convertido em tempo real. Eu sugiro usar esta extensão. Este método funciona perfeitamente sem preencher os números ao contrário. A String.Formatsolução parece funcionar ao contrário. Basta aplicar esta extensão à sua 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;
}
James Copeland
fonte
Funciona perfeito para avançar. Mas, ao voltar, ele fica preso no primeiro formato de (###).
Schwagmister
@Schwagmister Boa captura. Isso foi corrigido e refiz o código para uma extensão para uso geral.
James Copeland
4

Você também pode tentar o seguinte:

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

Resultado:

insira a descrição da imagem aqui

atik sarker
fonte
1
Esteja ciente de que diferentes países têm diferentes formatos e tamanhos de números de telefone e as pessoas não poderão inseri-los.
Neme
Como eu usaria isso com Html.DisplayFor (model => model.PhoneNumber)?
perfil completo de Juliana
Eu usei este e descobri como usá-lo na exibição da página Razor. Coloquei-o em um bloco @functions {} na parte superior da página. Então me livrei do auxiliar @ Html.DisplayFor e apenas referenciei a função: ................. @GetFormattedPhoneNumber (Model.Courses_New.CurrentContactPhone) Feito o meu dia!
JustJohn
4

Você pode se encontrar na situação em que há usuários tentando digitar números de telefone com todos os tipos de separadores entre o código de área e o bloco principal de números (por exemplo, espaços, traços, pontos, etc.). retire a entrada de todos os caracteres que não são números, para que você possa esterilizar a entrada com a qual está trabalhando. A maneira mais fácil de fazer isso é com uma expressão RegEx.

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

Em seguida, a resposta que você listou deve funcionar na maioria dos casos.

Para responder ao que você tem sobre o problema de extensão, você pode remover qualquer coisa que exceda a duração esperada de dez (para um número de telefone comum) e adicioná-lo ao final usando

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

Você desejará fazer uma verificação "se" para determinar se o comprimento da sua entrada é maior que 10 antes de fazer isso, se não, basta usar:

formattedPhoneNumber = Convert.ToInt64(value).ToString("###-###-####");
Victor Johnson
fonte
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
fonte
Votada, mas ... Esta é uma resposta do vb.net e a pergunta é c # #
entrada: 1234567890 saída: (123) 456-789 Não funciona!
MC9000
3
        string phoneNum;
        string phoneFormat = "0#-###-###-####";
        phoneNum = Convert.ToInt64("011234567891").ToString(phoneFormat);
nirav gandhi
fonte
2

Tente isto

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;

Felicidades.

Humberto Moreno
fonte
2

Use Match no Regex para dividir e, em seguida, produza uma string formatada com 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
fonte
2

A seguir, trabalharemos sem o uso de expressões regulares

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

Se não usarmos long.Parse, o string.format não funcionará.

Rama Krshna Ila
fonte
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;
}

A saída será: 001-568-895623

Mak
fonte
1

Por favor, use o seguinte link para C # http://www.beansoftware.com/NET-Tutorials/format-string-phone-number.aspx

A maneira mais fácil de fazer o formato é usando o 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;
}

Passe seu phoneNum como string 2021231234 até 15 caracteres.

FormatPhoneNumber(string phoneNum)

Outra abordagem seria usar 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;
    }
Mohammed Hossen
fonte
0

Para cuidar do seu problema de extensão, que tal:

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

Não para ressuscitar uma pergunta antiga, mas achei que eu poderia oferecer pelo menos um método um pouco mais fácil de usar, se um pouco mais complicado de uma configuração.

Portanto, se criarmos um novo formatador personalizado, podemos usar a formatação mais simples de string.Format sem precisar converter nosso número de telefone em umlong

Então, primeiro vamos criar o formatador personalizado:

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

Então, se você quiser usar isso, faça algo assim:

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

Algumas outras coisas em que pensar:

No momento, se você especificou um formatador mais longo do que uma string para formatar, apenas ignorará os sinais # adicionais. Por exemplo, issoString.Format(new NumericStringFormatter(),"{0:###-###-####}", "12345"); resultaria em 123-45-, portanto, convém que ele exija algum tipo de caractere de preenchimento possível no construtor.

Também não forneci uma maneira de escapar de um sinal de #, portanto, se você quisesse incluir isso em sua string de saída, não seria capaz de como está agora.

A razão de eu preferir esse método ao Regex é que geralmente tenho requisitos para permitir que os usuários especifiquem o formato eles mesmos e é consideravelmente mais fácil explicar como usar esse formato do que tentar ensinar um regex para o usuário.

Além disso, o nome da classe é um pouco inadequado, uma vez que realmente funciona para formatar qualquer sequência, desde que você queira mantê-la na mesma ordem e injetar caracteres dentro dela.

Kent Cooper
fonte
0

Você pode tentar {0: (000) 000 - ####} se o seu número de destino começar com 0.

Alice Guo
fonte
0

Aqui está outra maneira de fazê-lo.

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;
}
Neil Garcia
fonte