2008-11-04 10 views
101

Ajout rapide d'une exigence dans notre projet. Un champ dans notre base de données pour contenir un numéro de téléphone est configuré pour autoriser seulement 10 caractères. Donc, si je suis passé "(913) -444-5555" ou quoi que ce soit d'autre, existe-t-il un moyen rapide d'exécuter une chaîne à travers une sorte de fonction de remplacement spéciale que je peux lui passer un ensemble de caractères?Remplacer non numérique par une chaîne vide

Regex?

Répondre

206

Certainement regex:

string CleanPhone(string phone) 
{ 
    Regex digitsOnly = new Regex(@"[^\d]"); 
    return digitsOnly.Replace(phone, ""); 
} 

ou dans une classe pour éviter de recréer le regex tout le temps:

private static Regex digitsOnly = new Regex(@"[^\d]"); 

public static string CleanPhone(string phone) 
{ 
    return digitsOnly.Replace(phone, ""); 
} 

En fonction de vos entrées dans le monde réel, vous voudrez peut-être une certaine logique supplémentaire là pour faire des choses comme enlever les meneurs 1 (pour les longues distances) ou quelque chose traînant un x ou X (pour les extensions).

+0

C'est parfait. Ceci n'est utilisé qu'une ou deux fois, donc nous n'avons pas besoin de créer une classe, et en ce qui concerne le premier, ce n'est pas une mauvaise idée. Mais je pense que je préfère gérer cela au cas par cas, au moins dans ce projet. Merci encore - si je pouvais encore une fois, je le ferais. –

+1

J'attends quelqu'un pour poster une version de méthode d'extension de ceci pour la classe de corde :) –

+0

@Joel J'ai ajouté la version de méthode d'extension ci-dessous. Devinez les commentaires ne supportent pas markdown. – Aaron

3

Je suis sûr qu'il ya un moyen de faire plus efficace, mais je serais probablement faire:

string getTenDigitNumber(string input) 
{  
    StringBuilder sb = new StringBuilder(); 
    for(int i - 0; i < input.Length; i++) 
    { 
     int junk; 
     if(int.TryParse(input[i], ref junk)) 
      sb.Append(input[i]); 
    } 
    return sb.ToString(); 
} 
+0

C'était mon premier instinct, et c'était aussi pourquoi j'ai demandé ici. RegEx semble être une bien meilleure solution pour moi. Mais merci pour la réponse! –

65

Vous pouvez le faire facilement avec regex:

string subject = "(913)-444-5555"; 
string result = Regex.Replace(subject, "[^0-9]", ""); // result = "9134445555" 
+2

Refusé d'être une bonne réponse, mais Joel vous a battu. Merci pour la réponse si - j'aime vraiment voir la confirmation de plusieurs sources. –

+1

Voté parce que votre réponse est un one-liner. –

+0

@JoSmo Pour être juste, Joel's peut être converti en un one-liner plutôt trivialement. (Mais j'ai aussi upvoted: D) –

8

En utilisant les méthodes Regex .NET vous devriez être en mesure de faire correspondre un chiffre non numérique en utilisant \ D, comme ceci:

phoneNumber = Regex.Replace(phoneNumber, "\D", ""); 
+4

Ce n'est pas tout à fait raison. Vous avez besoin d'un @ ou "\\ D" pour échapper le \ dans l'expression rationnelle. En outre, vous devez utiliser String.Empty au lieu de "" – Bryan

-1

essayer ce

public static string cleanPhone(string inVal) 
     { 
      char[] newPhon = new char[inVal.Length]; 
      int i = 0; 
      foreach (char c in inVal) 
       if (c.CompareTo('0') > 0 && c.CompareTo('9') < 0) 
        newPhon[i++] = c; 
      return newPhon.ToString(); 
     } 
+0

'return newPhone.ToString();' retournera "System.Char []". Je pense que vous vouliez dire 'return new string (newPhone);', mais cela aussi filtre les nombres 0 et 9 à cause des '' '' 'et' <'au lieu de'> = 'et' <= '. Mais même alors, la chaîne aura des espaces de fin car le tableau 'newPhon' est plus long que nécessaire. – juharr

21

Voici la méthode d'extension de cette méthode.

public static class Extensions 
{ 
    public static string ToDigitsOnly(this string input) 
    { 
     Regex digitsOnly = new Regex(@"[^\d]"); 
     return digitsOnly.Replace(input, ""); 
    } 
} 
31

Vous n'avez pas besoin d'utiliser Regex.

phone = new String(phone.Where(c => char.IsDigit(c)).ToArray()) 
+3

Nice Réponse, pourquoi ajouter plus de référence à l'espace de nom RegularExpressions – BTE

+0

@BTE parce que c'est un raccourci qui utilise simplement 'system.linq;' –

+1

Comment cela fonctionne-t-il par rapport à la solution Regex? – Shavais

4

Que diriez-vous d'une méthode d'extension qui n'utilise pas regex.

Si vous respectez l'une des options Regex, utilisez au moins RegexOptions.Compiled dans la variable statique.

public static string ToDigitsOnly(this string input) 
{ 
    return new String(input.Where(char.IsDigit).ToArray()); 
} 

Ceci s'appuie sur la réponse d'Usman Zafar convertie en un groupe de méthodes.

4

pour les meilleures performances et la consommation de mémoire inférieure, essayez ceci:

using System; 
using System.Diagnostics; 
using System.Text; 
using System.Text.RegularExpressions; 

public class Program 
{ 
    private static Regex digitsOnly = new Regex(@"[^\d]"); 

    public static void Main() 
    { 
     Console.WriteLine("Init..."); 

     string phone = "001-12-34-56-78-90"; 

     var sw = new Stopwatch(); 
     sw.Start(); 
     for (int i = 0; i < 1000000; i++) 
     { 
      DigitsOnly(phone); 
     } 
     sw.Stop(); 
     Console.WriteLine("Time: " + sw.ElapsedMilliseconds); 

     var sw2 = new Stopwatch(); 
     sw2.Start(); 
     for (int i = 0; i < 1000000; i++) 
     { 
      DigitsOnlyRegex(phone); 
     } 
     sw2.Stop(); 
     Console.WriteLine("Time: " + sw2.ElapsedMilliseconds); 

     Console.ReadLine(); 
    } 

    public static string DigitsOnly(string phone, string replace = null) 
    { 
     if (replace == null) replace = ""; 
     if (phone == null) return null; 
     var result = new StringBuilder(phone.Length); 
     foreach (char c in phone) 
      if (c >= '0' && c <= '9') 
       result.Append(c); 
      else 
      { 
       result.Append(replace); 
      } 
     return result.ToString(); 
    } 

    public static string DigitsOnlyRegex(string phone) 
    { 
     return digitsOnly.Replace(phone, ""); 
    } 
} 

Le résultat de mon ordinateur est:
Init ...
Heure: 307
Heure: 2178

+0

+1 pour afficher les repères. Il est intéressant que la boucle avec StringBuilder surpasse RegEx, bien que je suppose que c'est logique quand RegEx doit probablement passer par beaucoup de règles pour décider quoi faire. –

Questions connexes