2014-12-04 6 views
5

Próbuję usunąć liczby na końcu danego ciągu znaków.Usuwanie liczb na końcu ciągu C#

AB123 -> AB 
123ABC79 -> 123ABC 

Próbowałem coś takiego;

string input = "123ABC79"; 
string pattern = @"^\\d+|\\d+$"; 
string replacement = ""; 
Regex rgx = new Regex(pattern); 
string result = rgx.Replace(input, replacement); 

Jednak zastępczy ciąg znaków jest taki sam jak wejście. Nie jestem zaznajomiony z regex. Mogę po prostu podzielić ciąg znaków na tablicę znaków i wykonać pętlę, aby to zrobić, ale nie jest to dobre rozwiązanie. Co to jest dobra praktyka, aby usunąć liczby, które są tylko na końcu łańcucha?

Z góry dziękuję.

+9

Deweloper ma problem. Wie, że może rozwiązać to za pomocą wyrażenia regularnego. Teraz ma dwa problemy. – Oliver

+0

Wiele razy słyszałem powiedzenie i rozumiem, o co chodzi. Ale co sugerowałbyś zamiast wyrażeń regularnych dla tego problemu? Pętla nad tablicą znaków jest bardziej brudna. – tdgtyugdyugdrugdr

+2

Może czuje się bardziej brudno, ale pod maską RegEx nie robi nic więcej. Utrzymywanie (być może) złożonego wyrażenia regularnego jest o wiele bardziej brudne niż wyrażanie tego samego w prostej pętli. Nie chcę mówić: "Nigdy nie używaj RegEx.", Ale powinieneś używać ich tylko wtedy, gdy naprawdę potrzebujesz, a także, być może, dodaj duży komentarz z wyjaśnieniem RegEx, ponieważ ma on tendencję do * pisania tylko * kod. Ach, i zanim zapomnę: Napisz test jednostkowy dla tej metody, który zostanie rozwiązany z wieloma różnymi ciągami (może za pomocą 'TestCaseSource'), aby upewnić się, że nic nie zepsujesz w przyszłości. – Oliver

Odpowiedz

10

Spróbuj:

string input = "123ABC79"; 
string pattern = @"\d+$"; 
string replacement = ""; 
Regex rgx = new Regex(pattern); 
string result = rgx.Replace(input, replacement); 

Umieszczenie $ na końcu będzie ograniczyć wyszukiwanie do podciągi numeryczne na końcu. Następnie, ponieważ wywołujemy Regex.Replace, musimy przekazać wzorzec zastępczy jako drugi parametr.

Demo

+1

Dziękuję, to obejmuje wszystkie podstawy. – tdgtyugdyugdrugdr

2

spróbuj tego:

string input = "123ABC79"; 
string pattern = @".+\D+(?=\d+)"; 
Match match = Regex.Match(input, pattern); 
string result = match.Value; 

ale można również użyć prostego cyklu:

string input = "123ABC79"; 
int i = input.Length - 1; 
for (; i > 0 && char.IsDigit(input[i - 1]); i--) 
{} 
string result = input.Remove(i); 
+0

Dziękuję bardzo Alex, to działa idealnie! – tdgtyugdyugdrugdr

+1

Należy jednak zauważyć, że nie robi to, co zostało zadane: nie usuwa numerów na końcu danych wejściowych, wybiera pierwszą cyfrę-nie-sekwencję z wejścia! – Heinzi

+0

@Heinzi wiem, ale sugeruję, że to jest to, co TS jest potrzebne, ale nie opisywałem dobrze –

1
(? <=[A-Za-z]*)\d* 

Powinna ona analizować

16

String.TrimEnd() jest szybsza niż przy użyciu wyrażenia regularnego:

var digits = new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; 
var input = "123ABC79"; 
var result = input.TrimEnd(digits); 

Benchmark aplikacja:

string input = "123ABC79"; 
    string pattern = @"\d+$"; 
    string replacement = ""; 
    Regex rgx = new Regex(pattern); 

    var iterations = 1000000; 
    var sw = Stopwatch.StartNew(); 
    for (int i = 0; i < iterations; i++) 
    { 
     rgx.Replace(input, replacement); 
    } 

    sw.Stop(); 
    Console.WriteLine("regex:\t{0}", sw.ElapsedTicks); 

    var digits = new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; 
    sw.Restart(); 
    for (int i = 0; i < iterations; i++) 
    { 
     input.TrimEnd(digits); 
    } 

    sw.Stop(); 
    Console.WriteLine("trim:\t{0}", sw.ElapsedTicks); 

Wynik:

regex: 40052843 
trim: 2000635