2010-10-19 18 views
6

Mam skompresowaną wartość ciągu, który wyodrębniam z pliku importu. Muszę sformatować to na numer paczki, który jest sformatowany w następujący sposób: ##-##-##-###-###. Dlatego ciąg "410151000640" powinien się "41-01-51-000-640". Mogę to zrobić za pomocą następującego kodu:Łańcuch formatu z kresek

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

Jednak ciąg może nie być wszystkimi liczbami; może mieć tam literę lub dwie, a zatem konwersja do int zakończy się niepowodzeniem. Czy istnieje sposób na to, aby każdy ciąg znaków, niezależnie od tego, czy jest to cyfra lub litera, będzie pasował poprawnie do formatu?

Odpowiedz

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

Albo nieco krótsza wersja

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

Działa jak urok! Wyodrębniłem to w metodzie opakowawczej z pewną poprawnością i obsługą błędów. Dzięki! – Kevin

+0

Muszę naprawdę nauczyć się Regex we właściwy sposób. Bardzo dobre rozwiązanie tego problemu. –

+1

@ Øyvind Jeśli to pomaga, chciałbym użyć strony http://www.regular-expressions.info/tutorial.html w celach informacyjnych. Mówią także o różnych smakach regex dostarczanych przez różne silniki. –

3

To powinno działać w Twoim przypadku:

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

Teraz value zawiera ciąg z kresek umieszczonych.

EDIT

Właśnie teraz zobaczyłem, że nie masz kreski pomiędzy każdą drugą liczbę całą drogę, to będzie wymagało niewielkiej uszczypnąć (i czyni to nieco bardziej niezdarny również Obawiam)

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

Podejdę do tego, używając własnej metody formatowania, o ile wiesz, że "Numer paczki" zawsze jest zgodny z określoną regułą.

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

Jeśli dobrze rozumiem, szukasz funkcji, która usuwa wszystkie litery z napisu, czyż nie?

Stworzyłem to na bieżąco, może można przekonwertować go na C# czy to, czego szukasz:

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

Nie, litery są również zawarte w numerze działki, na przykład "410151000vb6" powinno stać się "41-01-51-000-vb6" – Kevin

1

Jeśli jego częścią interfejsu użytkownika można użyć MaskedTextProvider w System.ComponentModel

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

Czy "a" w masce nie powinno być "&"? "a" jest alfanumeryczne, opcjonalne. Jedyne znaki, które zaakceptuje, to litery ASCII a-z i A-Z. http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask.aspx –

Powiązane problemy