Comment mettre en forme une chaîne en tant que numéro de téléphone en C #

163

J'ai une chaîne "1112224444" c'est un numéro de téléphone. Je veux formater comme 111-222-4444 avant de le stocker dans un fichier. Il est sur un enregistrement de données et je préférerais pouvoir le faire sans attribuer un nouveau variable.

Je pensais:

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

mais cela ne semble pas faire l'affaire.

** METTRE À JOUR **

D'accord. Je suis allé avec cette solution

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

Maintenant, il est foiré lorsque l'extension est inférieure à 4 chiffres. Il remplira les nombres de la droite. alors

1112224444 333  becomes

11-221-244 3334

Des idées?

Brian G
la source
5
Veuillez noter que pas partout n'a de numéros de téléphone à 10 chiffres, ou utilise le format 111-222-4444.
Dour High Arch
Cela échouera avec les numéros de téléphone commençant par 0
dano
Vous devez spécifier s'il s'agit uniquement de numéros nord-américains ou non.
Armstrongest
AVERTISSEMENT: le fil entier utilise les numéros de téléphone américains nord-américains. Utilisez une bibliothèque qui prend en charge les numéros internationaux. nuget.org/packages/libphonenumber-csharp
Sean Anderson

Réponses:

204

Veuillez noter que cette réponse fonctionne avec les types de données numériques (int, long). Si vous commencez par une chaîne, vous devrez d'abord la convertir en nombre. Veuillez également prendre en compte le fait que vous devrez valider que la chaîne initiale comporte au moins 10 caractères.

À partir d'une bonne page pleine d'exemples:

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

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

Bien qu'une expression régulière puisse fonctionner encore mieux, gardez à l'esprit l'ancienne citation de programmation:

Certaines personnes, confrontées à un problème, pensent: «Je sais, j'utiliserai des expressions régulières». Maintenant, ils ont deux problèmes.
--Jamie Zawinski, dans comp.lang.emacs

Sean
la source
Que se passe-t-il, disons s'il manque quelques chiffres au numéro de téléphone - comme "800555" seulement? y a-t-il un moyen d'afficher uniquement ce qui y est présent?
VoodooChild
11
C'est une mauvaise implémentation car si l'indicatif régional commence par 0105555555 ou quelque chose comme ça, vous finissez par récupérer (01) 555-5555 au lieu de (010) 555-5555. La raison en est que si vous convertissez le numéro de téléphone en un nombre, le zéro à l'avant est considéré comme n'étant rien et lorsque vous le formatez, le premier 0 est supprimé.
Paul Mendoza
3
@Paul Veuillez lire la définition du problème: "J'ai une chaîne" 1112224444 'c'est un numéro de téléphone. Je veux formater en tant que 111-222-4444 avant de le stocker dans un fichier. "
Sean
39
Cela ne fonctionnera pas si votre numéro de téléphone est une chaîne, comme l'indiquent les questions, à moins que vous ne les convertissiez d'abord en une valeur numérique.
JustinStolle
4
Je sais que cela ne fait que répéter le commentaire ci-dessus, mais cette réponse n'a pas répondu à la question. Comment formatez-vous une chaîne dans un format spécifique, dans ce cas un format de numéro de téléphone.
dyslexicanaboko
168

Je préfère utiliser des expressions régulières:

Regex.Replace("1112224444", @"(\d{3})(\d{3})(\d{4})", "$1-$2-$3");
Ryan Duffield
la source
4
Je suppose que cela fonctionnerait, mais le format .ToString () est plus facile à lire et devrait mieux fonctionner.
Joel Coehoorn
14
Si j'ai déjà affaire à une ficelle, comme l'a dit l'affiche, la lancer sur un long et en arrière semble ridicule.
Ryan Duffield
C'est peut-être ce dont j'ai besoin après tout. peut mieux gérer l'extension
Brian G
5
+1 pour conserver le numéro sous forme de chaîne (étant donné que souvent les numéros de téléphone utilisés pour les systèmes SMS automatisés doivent être stockés au format +44)
Ed James
3
Je travaille avec différents formats (par exemple (111) 222-4444, 111.222.4444, etc.), mais j'ai besoin qu'ils soient normalisés à (111) 222-4444. Je voulais aussi me protéger contre les nombres incomplets et utilisé la notation {n, m} . (Et mes excuses pour le formatage, mais certains formats MD ne fonctionnent pas pour moi). // 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

Vous devrez le diviser en sous-chaînes. Bien que vous puissiez le faire sans aucune variable supplémentaire, ce ne serait pas particulièrement agréable. Voici une solution potentielle:

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
la source
Jon êtes-vous sûr qu'il vaut mieux créer trois sous-chaînes que d'utiliser string.format?
Pradeep
J'utilise également String.Format - mais comment suggérez-vous d'obtenir le résultat sans utiliser String.Format?
Jon Skeet
2
J'ai emballé ça dans un if (phone.Length == 10)état.
Zack Peterson
Plus One - Un petit point: ce format ne semble pas avoir de parenthèses autour de l'indicatif régional, peut-être que je le lis mal.
Mark Rogers
1
@MarkRogers: La question dit "Je veux formater comme 111-222-4444" - il n'y a pas de parenthèses ici.
Jon Skeet
28

Je suggère cela comme une solution propre pour les chiffres américains.

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
la source
1
Cela a fonctionné pour moi à l'exception que j'ai dû ajouter une vérification pour m'assurer que la valeur du téléphone n'était pas NULL ou Whitespace en premier.
Caverman
1
Cela a fonctionné pour moi après tous ceux que j'ai essayés ci
dessus
22

Autant que je sache, vous ne pouvez pas faire cela avec string.Format ... vous devrez gérer cela vous-même. Vous pouvez simplement supprimer tous les caractères non numériques, puis faire quelque chose comme:

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

Cela suppose que les données ont été saisies correctement, que vous pouvez utiliser des expressions régulières pour valider.

mattruma
la source
4
Et cela suppose un numéro de téléphone nord-américain
Chris
19

Cela devrait fonctionner:

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

OU dans votre cas:

String.Format("{0:###-###-####}", Convert.ToInt64("1112224444"));
Vivek Shenoy
la source
3
1 petit problème si j'utilise 01213456789 ses marques (12) 345-6789 ... une solution ...?
Sangram Nandkhile
5
C'est la meilleure solution. Le zéro en tête est sans objet en ce qui concerne les numéros de téléphone américains car il n'y a pas d'indicatif régional américain commençant par zéro ou un.
JB
Petit problème si j'ai essayé 12345678, il formate (1) 234-5678 ... Mais ce dont j'ai besoin, c'est (123) 456-78. Existe-t-il une solution à ça? Merci
Kavitha P.
14

Si vous pouvez obtenir en i["MyPhone"]tant que long, vous pouvez utiliser la long.ToString()méthode pour le formater:

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

Consultez la page MSDN sur les chaînes de format numérique .

Veillez à utiliser long plutôt que int: int pourrait déborder.

Joël Coehoorn
la source
1
Le problème avec ceci est si le nombre est> 10 caractères de long (c.-à-d. Inclut une extension). Cela se traduit par une représentation très étrange où 212-555-1212 x1234 sort comme2125551-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
souligner
la source
entrée: 1234567890 sortie:
123456
5

Si vous recherchez un numéro de téléphone (américain) à convertir en temps réel. Je suggère d'utiliser cette extension. Cette méthode fonctionne parfaitement sans remplir les nombres à l'envers. La String.Formatsolution semble fonctionner à l'envers. Appliquez simplement cette extension à votre chaîne.

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
la source
Fonctionne parfaitement pour le mouvement vers l'avant. Mais en revenant, il reste bloqué au premier format de (###).
Schwagmister
@Schwagmister Bonne prise. Cela a été corrigé et j'ai refactoré le code en une extension pour un usage général.
James Copeland
4

Vous pouvez également essayer ceci:

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

Production:

entrez la description de l'image ici

atik sarker
la source
1
Sachez que différents pays ont des formats et des longueurs de numéros de téléphone différents et que les gens ne pourront pas les saisir.
Neme
Comment utiliserais-je cela avec Html.DisplayFor (model => model.PhoneNumber)?
JustJohn
J'ai utilisé celui-ci et compris comment l'utiliser dans l'affichage de la page Razor. Je l'ai mis dans un bloc @functions {} en haut de la page. Ensuite, je me suis débarrassé de l'aide @ Html.DisplayFor et j'ai juste référencé la fonction: ................. @GetFormattedPhoneNumber (Model.Courses_New.CurrentContactPhone) Fait ma journée!
JustJohn
4

Vous pouvez vous retrouver dans la situation où des utilisateurs essaient d'entrer des numéros de téléphone avec toutes sortes de séparateurs entre l'indicatif régional et le bloc de numéro principal (par exemple, des espaces, des tirets, des points, etc.). effacez l'entrée de tous les caractères qui ne sont pas des nombres afin de pouvoir stériliser l'entrée avec laquelle vous travaillez. Le moyen le plus simple de procéder consiste à utiliser une expression RegEx.

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

Ensuite, la réponse que vous avez énumérée devrait fonctionner dans la plupart des cas.

Pour répondre à ce que vous avez sur votre problème d'extension, vous pouvez supprimer tout ce qui est plus long que la longueur attendue de dix (pour un numéro de téléphone normal) et l'ajouter à la fin en utilisant

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

Vous voudrez faire une vérification `` si '' pour déterminer si la longueur de votre entrée est supérieure à 10 avant de faire cela, sinon, utilisez simplement:

formattedPhoneNumber = Convert.ToInt64(value).ToString("###-###-####");
Victor Johnson
la source
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
qc
la source
Voté mais ... Ceci est une réponse de vb.net et la question est c #
entrée: 1234567890 sortie: (123) 456-789 Ne fonctionne pas!
MC9000 du
3
        string phoneNum;
        string phoneFormat = "0#-###-###-####";
        phoneNum = Convert.ToInt64("011234567891").ToString(phoneFormat);
nirav gandhi
la source
2

Essaye ça

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;

À votre santé.

Humberto Moreno
la source
2

Utilisez Match in Regex pour fractionner, puis générer une chaîne formatée avec 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
la source
2

Ce qui suit fonctionnera sans utilisation d'expression régulière

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

Si nous n'utilisons pas long.Parse, le string.format ne fonctionnera pas.

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

La sortie sera: 001-568-895623

Mak
la source
1

Veuillez utiliser le lien suivant pour C # http://www.beansoftware.com/NET-Tutorials/format-string-phone-number.aspx

Le moyen le plus simple de formater est d'utiliser 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;
}

Passez votre phoneNum sous forme de chaîne 2021231234 jusqu'à 15 caractères.

FormatPhoneNumber(string phoneNum)

Une autre approche serait d'utiliser 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
la source
0

Pour résoudre votre problème d'extension, que diriez-vous:

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

Pas pour ressusciter une vieille question, mais j'ai pensé que je pourrais proposer au moins une méthode un peu plus facile à utiliser, même si une configuration un peu plus compliquée.

Donc, si nous créons un nouveau formateur personnalisé, nous pouvons utiliser le formatage plus simple de string.Formatsans avoir à convertir notre numéro de téléphone en unlong

Commençons par créer le formateur personnalisé:

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

Donc, si vous voulez utiliser ceci, vous feriez quelque chose comme ceci:

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

Quelques autres choses à penser:

À l'heure actuelle, si vous avez spécifié un formateur plus long qu'une chaîne pour formater, il ignorera simplement les signes # supplémentaires. Par exemple, cela String.Format(new NumericStringFormatter(),"{0:###-###-####}", "12345");donnerait 123-45- donc vous voudrez peut-être qu'il prenne une sorte de caractère de remplissage possible dans le constructeur.

De plus, je n'ai pas fourni de moyen d'échapper au signe #, donc si vous vouliez l'inclure dans votre chaîne de sortie, vous ne seriez pas en mesure de le faire actuellement.

La raison pour laquelle je préfère cette méthode à Regex est que j'ai souvent des exigences pour permettre aux utilisateurs de spécifier le format eux-mêmes et il est considérablement plus facile pour moi d'expliquer comment utiliser ce format que d'essayer d'enseigner une expression régulière à un utilisateur.

De plus, le nom de la classe est un peu inapproprié car il fonctionne en fait pour formater n'importe quelle chaîne tant que vous voulez la garder dans le même ordre et simplement injecter des caractères à l'intérieur.

Kent Cooper
la source
0

Vous pouvez essayer {0: (000) 000 - ####} si votre numéro cible commence par 0.

Alice Guo
la source
0

Voici une autre façon de procéder.

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
la source