2010-10-19 5 views
6

J'ai une valeur de chaîne compressée que j'extrempe d'un fichier d'importation. J'ai besoin de formater ceci en un numéro de parcelle, qui est formaté comme suit: ##-##-##-###-###. Par conséquent, la chaîne "410151000640" doit devenir "41-01-51-000-640". Je peux le faire avec le code suivant:Chaîne de format avec des tirets

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

Cependant, la chaîne ne peut pas être tous les nombres; il pourrait y avoir une lettre ou deux, et ainsi la conversion à l'int échouera. Existe-t-il un moyen de faire cela sur une chaîne de caractères de sorte que chaque caractère, qu'il s'agisse d'un nombre ou d'une lettre, rentrera correctement dans le format?

Répondre

19
Regex.Replace("410151000640", @"^(.{2})(.{2})(.{2})(.{3})(.{3})$", "$1-$2-$3-$4-$5"); 

Ou la version légèrement plus courte

Regex.Replace("410151000640", @"^(..)(..)(..)(...)(...)$", "$1-$2-$3-$4-$5"); 
+0

Fonctionne comme un charme! J'ai extrait ceci dans une méthode de wrapper avec un peu de validation et de gestion des erreurs. Merci! – Kevin

+0

Je dois vraiment apprendre Regex correctement moi-même. Une très bonne solution à ce problème. –

+1

@ Øyvind Si cela aide, j'aime utiliser http://www.regular-expressions.info/tutorial.html pour référence. Ils parlent également des différentes saveurs de regex fournies par différents moteurs. –

3

Cela devrait fonctionner dans votre cas:

string value = "410151000640"; 
for(int i = 2; i < value.Length; i+=3){ 
    value = value.Insert(i, "-"); 
} 

Maintenant value contient la chaîne avec des tirets insérés.

EDIT

Je viens maintenant vu que vous n'avez pas des tirets entre chaque deuxième numéro tout le chemin, à cela nécessitera un petit coup sec (et en fait un peu plus maladroit aussi j'ai peur)

string value = "410151000640"; 
for(int i = 2; i < value.Length-1; i+=3){ 
    if(value.Count(c => c == '-') >= 3) i++; 
    value = value.Insert(i, "-"); 
} 
8

Je voudrais aborder cela en ayant votre propre méthode de mise en forme, aussi longtemps que vous savez que le "numéro de parcelle" est toujours conforme à une règle spécifique.

public static string FormatParcelNumber(string input) 
{ 
    if(input.length != 12) 
    throw new FormatException("Invalid parcel number. Must be 12 characters"); 

    return String.Format("{0}-{1}-{2}-{3}-{4}", 
       input.Substring(0,2), 
       input.Substring(2,2), 
       input.Substring(4,2), 
       input.Substring(6,3), 
       input.Substring(9,3)); 
} 
0

Si je vous comprends bien, vous cherchez une fonction qui supprime toutes les lettres d'une chaîne, n'est-ce pas?

J'ai créé ce à la volée, vous pouvez peut-être convertir en C# si c'est ce que vous cherchez:

Dim str As String = "410151000vb640" 
str = String.Format("{0:##-##-##-###-###}", Convert.ToInt64(MakeNumber(str))) 


Public Function MakeNumber(ByVal stringInt As String) As String 
    Dim sb As New System.Text.StringBuilder 
    For i As Int32 = 0 To stringInt.Length - 1 
     If Char.IsDigit(stringInt(i)) Then 
      sb.Append(stringInt(i)) 
     End If 
    Next 
    Return sb.ToString 
End Function 
+0

Non, les lettres sont également incluses dans le numéro de paquet, par exemple "410151000vb6" devrait devenir "41-01-51-000-vb6" – Kevin

1

Si la partie de l'interface utilisateur, vous pouvez utiliser MaskedTextProvider dans System.ComponentModel

MaskedTextProvider prov = new MaskedTextProvider("aa-aa-aa-aaa-aaa"); 
    prov.Set("41x151000a40"); 
    string result = prov.ToDisplayString(); 
+0

Le 'a' de votre masque ne devrait-il pas être '&'? 'a' est alphanumérique, facultatif. Les seuls caractères acceptés seront les lettres ASCII a-z et A-Z. http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask.aspx –

Questions connexes