Come formattare una stringa come numero di telefono in C #


163

Ho una stringa "1112224444" è un numero di telefono. Voglio formattare come 111-222-4444 prima di memorizzarlo in un file. È su un datarecord e preferirei poterlo fare senza assegnare un nuovo variabile.

Stavo pensando:

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

ma questo non sembra fare il trucco.

** AGGIORNARE **

Ok. Sono andato con questa soluzione

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

Ora viene incasinato quando l'estensione è inferiore a 4 cifre. Riempirà i numeri da destra. così

1112224444 333  becomes

11-221-244 3334

Qualche idea?


5
Si prega di essere consapevoli del fatto che non ovunque ha numeri di telefono a 10 cifre o utilizza il formato 111-222-4444.
Dour High Arch,

Questo fallirà con i numeri di telefono che iniziano con 0
dano

È necessario specificare se si tratta solo di numeri nordamericani o meno.
Armstrongest,

ATTENZIONE: l'intero thread assume i numeri di telefono statunitensi del Nord America. Utilizzare una libreria che supporta numeri internazionali. nuget.org/packages/libphonenumber-csharp
Sean Anderson

Risposte:


204

Si noti che questa risposta funziona con tipi di dati numerici (int, long). Se inizi con una stringa, devi prima convertirla in un numero. Inoltre, tieni presente che dovrai convalidare che la stringa iniziale contiene almeno 10 caratteri.

Da una buona pagina piena di esempi:

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

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

Sebbene un regex possa funzionare ancora meglio, tieni presente la vecchia citazione di programmazione:

Alcune persone, di fronte a un problema, pensano "Lo so, userò espressioni regolari". Ora hanno due problemi.
- Jamie Zawinski, in comp.lang.emacs


Cosa succede, diciamo se al numero di telefono mancano poche cifre, come solo "800555"? c'è un modo per visualizzare solo ciò che è presente lì?
VoodooChild

11
Questa è un'implementazione sbagliata perché se il prefisso inizia con 0105555555 o qualcosa del genere, si finisce per tornare indietro (01) 555-5555 anziché (010) 555-5555. Il motivo è che se si converte il numero di telefono in un numero, lo zero nella parte anteriore viene visto come non essere nulla e e quando lo si formatta il primo 0 viene eliminato.
Paul Mendoza,

3
@Paul Si prega di leggere la definizione del problema: "I have a string" 1112224444 'è un numero di telefono. Voglio formattare come 111-222-4444 prima di memorizzarlo in un file ".
Sean

39
Questo non funzionerà se il tuo numero di telefono è una stringa, come indicato dalle domande, a meno che non lo converti prima in un valore numerico.
JustinStolle,

4
So che questo sta solo ripetendo il commento sopra, ma questa risposta non ha risposto alla domanda. Come formattare una stringa in un formato specifico, in questo caso un formato di numero di telefono.
dyslexicanaboko,

168

Preferisco usare espressioni regolari:

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

4
Suppongo che funzionerebbe, ma il formato .ToString () è più facile da leggere e dovrebbe funzionare meglio.
Joel Coehoorn,

14
Se ho già a che fare con una corda, come ha detto il poster, lanciarla a lungo e viceversa sembra sciocca.
Ryan Duffield,

Forse questo è quello che mi serve dopo tutto. potrebbe gestire meglio l'estensione
Brian G

5
+1 per mantenere il numero come una stringa (dato che spesso i numeri di telefono utilizzati per i sistemi SMS automatizzati devono essere memorizzati nel formato +44)
Ed James,

3
Sto lavorando con vari formati (ad es. (111) 222-4444, 111.222.4444, ecc.), Ma ho bisogno che siano normalizzati a (111) 222-4444. Volevo anche proteggermi da numeri incompleti e ho usato la notazione {n, m} . (E mi scuso per la formattazione, ma alcuni dei formati MD non funzionano per me). // 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,

47

Dovrai romperlo in sottostringhe. Mentre si potrebbe farlo senza alcuna variabile in più, non sarebbe particolarmente bello. Ecco una potenziale soluzione:

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 sei sicuro che fare tre sottostringhe sia meglio che usare string.format?
Pradeep,

Uso anche String.Format, ma come stai suggerendo di ottenere il risultato senza usare String.Format?
Jon Skeet,

2
L'ho avvolto in una if (phone.Length == 10)condizione.
Zack Peterson,

Più uno - Un piccolo punto: quel formato non sembra avere parentesi attorno al prefisso, forse sto leggendo male.
Mark Rogers,

1
@MarkRogers: la domanda dice "Voglio formattare come 111-222-4444" - non ci sono parentesi lì.
Jon Skeet,

28

Lo consiglio come una soluzione pulita per i numeri statunitensi.

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
Questo ha funzionato per me con l'eccezione che ho dovuto aggiungere un segno di spunta per assicurarmi che il valore del telefono non fosse prima NULL o Spazio bianco.
Caverman,

1
Questo ha funzionato per me dopo tutti quelli sopra che ho provato
Eliotjse il

22

Per quanto ne so non puoi farlo con string.Format ... dovresti gestirlo da solo. Potresti semplicemente eliminare tutti i caratteri non numerici e fare qualcosa del tipo:

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

Ciò presuppone che i dati siano stati immessi correttamente, che è possibile utilizzare espressioni regolari per convalidare.


4
E presuppone un numero di telefono nordamericano
chris,

19

Questo dovrebbe funzionare:

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

O nel tuo caso:

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

3
1 piccolo problema se sto usando 01213456789 fa (12) 345-6789 ... qualche soluzione ...?
Sangram Nandkhile,

5
Questa è la soluzione migliore Lo zero iniziale è discutibile rispetto ai numeri di telefono americani in quanto non ci sono prefissi americani che iniziano con zero o uno.
JB

Piccolo problema se ho provato 12345678, formatta (1) 234-5678 ... Ma quello di cui ho bisogno è (123) 456-78. C'è qualche soluzione per questo? Grazie
Kavitha P.

14

Se riesci a ottenere i["MyPhone"]come long, puoi utilizzare il long.ToString()metodo per formattarlo:

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

Vedi la pagina MSDN su Stringhe di formato numerico .

Fai attenzione a usare long piuttosto che int: int potrebbe traboccare.


1
Il problema è che se il numero è lungo> 10 caratteri (ovvero include un'estensione). Ciò si traduce in una rappresentazione molto strana in cui esce 212-555-1212 x1234 come2125551-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

input: 1234567890 output: 123 456 78 90 non funziona
MC9000

5

Se stai cercando un numero di telefono (USA) da convertire in tempo reale. Suggerisco di usare questa estensione. Questo metodo funziona perfettamente senza compilare i numeri all'indietro. La String.Formatsoluzione sembra funzionare all'indietro. Basta applicare questa estensione alla stringa.

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

Funziona perfettamente per il movimento in avanti. Ma quando ritorna, rimane bloccato nel primo formato di (###).
Schwagmister,

@Schwagmister Buona cattura. Questo è stato corretto e ho refactored il codice in un'estensione per uso generale.
James Copeland,

4

Puoi anche provare questo:

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

Produzione:

inserisci qui la descrizione dell'immagine


1
Tieni presente che paesi diversi hanno formati e lunghezze di numeri di telefono diversi e che le persone non potranno inserirli.
Neme,

Come lo userei con Html.DisplayFor (model => model.PhoneNumber)?
JustJohn,

Ho usato questo e ho capito come usarlo nella visualizzazione della pagina del rasoio. L'ho inserito in un blocco @functions {} nella parte superiore della pagina. Quindi mi sono sbarazzato dell'helper @ Html.DisplayFor e ho appena fatto riferimento alla funzione: ................. @GetFormattedPhoneNumber (Model.Courses_New.CurrentContactPhone) Ha reso la mia giornata!
JustJohn,

4

Potresti trovarti nella situazione in cui hai utenti che cercano di inserire numeri di telefono con tutti i tipi di separatori tra il prefisso e il blocco numerico principale (ad es. Spazi, trattini, punti, ecc ...) Quindi vorrai rimuovere l'input di tutti i caratteri che non sono numeri in modo da poter sterilizzare l'input con cui si sta lavorando. Il modo più semplice per farlo è con un'espressione RegEx.

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

Quindi la risposta che hai elencato dovrebbe funzionare nella maggior parte dei casi.

Per rispondere a ciò che hai sul problema con l'estensione, puoi rimuovere tutto ciò che è più lungo della lunghezza prevista di dieci (per un numero di telefono normale) e aggiungerlo alla fine usando

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

Ti consigliamo di fare un controllo 'if' per determinare se la lunghezza del tuo input è maggiore di 10 prima di farlo, altrimenti usa semplicemente:

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

Votato ma ... Questa è una risposta vb.net e la domanda è c #

input: 1234567890 output: (123) 456-789 Non funziona!
MC9000,

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

2

Prova questo

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;

Saluti.


2

Usa Abbina in Regex per dividere, quindi emetti una stringa formattata con 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

Di seguito funzionerà senza l'uso di espressioni regolari

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

Se non usiamo long.Parse, string.format non funzionerà.


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

L'output sarà: 001-568-895623


1

Utilizzare il seguente link per C # http://www.beansoftware.com/NET-Tutorials/format-string-phone-number.aspx

Il modo più semplice per formattare è usare 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;
}

Passa il numero del telefono come stringa 2021231234 fino a 15 caratteri.

FormatPhoneNumber(string phoneNum)

Un altro approccio sarebbe quello di usare 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

Per risolvere il problema relativo all'estensione, che ne dici di:

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

0

Non per resuscitare una vecchia domanda, ma ho pensato che avrei potuto offrire almeno un metodo leggermente più semplice da usare, se un po 'più complicato di una configurazione.

Quindi, se creiamo un nuovo formattatore personalizzato, possiamo usare la formattazione più semplice di string.Formatsenza dover convertire il nostro numero di telefono in along

Quindi prima di tutto creiamo il formatter personalizzato:

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

Quindi, se si desidera utilizzare questo, si dovrebbe fare qualcosa di simile:

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

Alcune altre cose a cui pensare:

In questo momento, se hai specificato un formattatore più lungo di una stringa da formattare, ignorerà solo i segni # aggiuntivi. Ad esempio, ciò String.Format(new NumericStringFormatter(),"{0:###-###-####}", "12345");comporterebbe 123-45- quindi potresti voler avere un qualche tipo di carattere di riempimento nel costruttore.

Inoltre, non ho fornito un modo per sfuggire a un segno #, quindi se volessi includerlo nella stringa di output non saresti in grado di farlo al momento.

Il motivo per cui preferisco questo metodo a Regex è che spesso ho i requisiti per consentire agli utenti di specificare il formato da soli ed è molto più facile per me spiegare come usare questo formato piuttosto che provare a insegnare a regex un utente.

Anche il nome della classe è un po 'improprio in quanto funziona effettivamente per formattare qualsiasi stringa fintanto che vuoi mantenerlo nello stesso ordine e solo iniettare caratteri al suo interno.


0

Puoi provare {0: (000) 000 - ####} se il tuo numero di destinazione inizia con 0.


0

Ecco un altro modo di farlo.

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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.