Wie erhalte ich die letzten vier Zeichen aus einer Zeichenfolge in C #?


309

Angenommen, ich habe eine Zeichenfolge:

"34234234d124"

Ich möchte die letzten vier Zeichen dieser Zeichenfolge erhalten "d124". Ich kann verwenden SubString, aber es braucht ein paar Codezeilen, einschließlich der Benennung einer Variablen.

Ist es möglich, dieses Ergebnis in einem Ausdruck mit C # zu erhalten?


3
Was möchten Sie, wenn weniger als 4 Zeichen vorhanden sind?
Agent-j

12
4 > mystring.length ? mystring : mystring.Substring(mystring.length -4);
Jodrell

3
In Python ist die Lösung einfach : "hello world"[-4:]. Ich hoffe, dass eine zukünftige Version von C # es so einfach macht.
Colonel Panic

@ColonelPanic, jetzt kannst du mit C # 8.0 : "hello world"[^4..]:-)
Frode Evensen

Antworten:


407
mystring.Substring(Math.Max(0, mystring.Length - 4)); //how many lines is this?

Wenn Sie sicher sind, dass die Länge Ihrer Saite mindestens 4 beträgt, ist sie sogar noch kürzer:

mystring.Substring(mystring.Length - 4);

13
Außerdem schlägt es fehl, wenn mystringes weniger als 4 Zeichen lang ist.
George Duckett

3
+1, weil ich denke, dass Ihre etwas besser lesbar ist als die von @ dtb
George Duckett

Ein paar Codezeilen (die das OP bereits kannte) in eine Zeile zu packen, ist nicht wirklich dasselbe wie ein Ausdruck.
Buh Buh

1
Ich mag das. Einfach und elegant und maximal. Wenn Ihre Zeichenfolge kleiner als 0 ist, erhalten Sie keine Ausnahme vom Index.
Bretticus

+1 einfach und auf den Punkt, deckt alle Grundlagen ab. Die von Stecya vorgeschlagene Erweiterungsmethode ist ebenfalls gut, aber etwas übertrieben, wenn Sie sie nur einmal ausführen.
Morvael

205

Sie können eine Erweiterungsmethode verwenden :

public static class StringExtension
{
    public static string GetLast(this string source, int tail_length)
    {
       if(tail_length >= source.Length)
          return source;
       return source.Substring(source.Length - tail_length);
    }
}

Und dann anrufen:

string mystring = "34234234d124";
string res = mystring.GetLast(4);

11
Ich mag das, aber ich würde es wahrscheinlich einfach Last () nennen. Immerhin ist Substring () nicht GetSubstring ().
Buh Buh

21
Nennen Sie es vielleicht Tail (), da Last mit der Linq Extension Last () kollidiert.
Craig Curtis

5
+1 für "viel länger als 1 Zeile". Es ist so ärgerlich, unlesbaren Code zu sehen, weil Zeilen eingespart werden.
Fabio Milheiro

2
Oder nennen Sie es Right (), um die Konsistenz mit VisualBasic gemäß der Antwort von @RJ Programmer zu gewährleisten (ich möchte keine weitere Assembly nur für eine Funktion hinzufügen).
Weihnachten

3
Ich liebe diese Lösung.
Luke

46

Alles was du tun musst, ist..

String result = mystring.Substring(mystring.Length - 4);

2
Nicht, wenn Sie möchten, dass eine Ausnahme ausgelöst wird, wenn die Länge weniger als 4 beträgt ...
Milos Mrdovic

45

Ok, ich sehe, dass dies ein alter Beitrag ist, aber warum schreiben wir Code neu, der bereits im Framework bereitgestellt wird?

Ich würde vorschlagen, dass Sie einen Verweis auf die Framework-DLL "Microsoft.VisualBasic" hinzufügen.

using Microsoft.VisualBasic;
//...

string value = Strings.Right("34234234d124", 4);

8
Schönes Beispiel für eine Zeit, um die VB-Funktionalität zu nutzen
Brian White

3
Ich liebe dich. Der größte Teil meiner Programmiererfahrung ist VB, daher ist es fantastisch herauszufinden, dass ich all die Funktionen nutzen kann, mit denen ich so vertraut bin
Ben Strombeck

6
Ich kann nie herausfinden, ob die Verwendung von MS.VB eine gute Idee ist - warum wird es in den VisualBasicNamespace verschoben ? TextFieldParserist ein weiteres Beispiel. Warum werden diese Dienstprogramme so seltsam berücksichtigt?
Ruffin

6
Ich denke, dies sollte die akzeptierte Antwort sein. Warum das Rad neu erfinden?
Zack

2
@Bomboca: Wir können sicher sein, dass es so lange weitergeht, wie Microsoft Visual Basic weiterhin unterstützt. Es ist in der Version 4.6 enthalten und ich kann weder explizite noch implizite Angaben von MS finden, dass sie die Unterstützung von VB.Net als Entwicklungssprache einstellen wollen.
RJ Programmer

30
string mystring = "34234234d124";
mystring = mystring.Substring(mystring.Length-4)

26

Die Verwendung von Teilzeichenfolgen ist eigentlich recht kurz und lesbar:

 var result = mystring.Substring(mystring.Length - Math.Min(4, mystring.Length));
 // result == "d124"

17

Hier ist eine weitere Alternative, die (aufgrund der verzögerten Ausführung ) nicht zu schlecht abschneiden sollte :

new string(mystring.Reverse().Take(4).Reverse().ToArray());

Obwohl eine Erweiterungsmethode für diesen Zweck mystring.Last(4)eindeutig die sauberste Lösung ist, wenn auch etwas mehr Arbeit.


1
@BrianWhite Die Leute sind nach Neujahr verärgert?
Konrad Viltersten

1
Schöne Lösung. ich mag das. Aber Sie haben andere Reverse vergessen, um die richtige Zeichenfolge zu erhalten. Muss sein: neuer String (mystring.Reverse (). Take (4) .Reverse (). ToArray ());
Yuri Morales

Aah ja, du hast recht - mein mentaler Compiler hat nicht so weit gedacht. Leider macht es das noch schlimmer! :)
Andre Luus

1
Wegen ToArray gibt es keine verzögerte Ausführung

1
Ich glaube nicht, dass Sie verstehen, @ BjörnAliGöransson, mein Punkt war, dass Reverse().Take(4).Reverse()nicht jeder die gesamte Zeichenfolge auflistet , sondern nur beim letzten ToArrayAufruf. Wenn es keine verzögerte Ausführung gäbe, würde dies bedeuten Reverse().ToArray().Take(4).ToArray().Reverse().ToArray(). Dies setzt natürlich voraus, dass es sich bei diesen Erweiterungen um den verzögerten Typ handelt - den ich nicht überprüft habe. Die String-Konstruktoren akzeptieren IEnumerable nicht, daher müssen Sie es zu diesem Zeitpunkt in ein Array auflisten.
Andre Luus

17

Sie können einfach die SubstringMethode von C # verwenden. Zum Beispiel.

string str = "1110000";
string lastFourDigits = str.Substring((str.Length - 4), 4);

Es wird das Ergebnis 0000 zurückgegeben.


7
Dies wurde wie 28 Mal beantwortet und Sie haben es erneut hinzugefügt? Und warum sollte man die Zwei-Parameter-Überladung anstelle derjenigen verwenden, die nur empfängt startIndex?
Andrew

Genau die Antwort, die ich brauchte. Danke für das Teilen von @Amit Kumawat.
Daryl

12

Eine einfache Lösung wäre:

string mystring = "34234234d124";
string last4 = mystring.Substring(mystring.Length - 4, 4);

7
mystring = mystring.Length > 4 ? mystring.Substring(mystring.Length - 4, 4) : mystring;

Schön, aber ich denke, das hast du =nicht gemeint =+.
Dotancohen

1
mystring.Substring (mystring.Length - 4, 4) ist dasselbe wie: mystring.Substring (mystring.Length - 4)
Moe Howard

6

Es ist nur das:

int count = 4;
string sub = mystring.Substring(mystring.Length - count, count);

6

Im Vergleich zu einigen früheren Antworten besteht der Hauptunterschied darin, dass dieser Code berücksichtigt, wenn die Eingabezeichenfolge lautet:

  1. Null
  2. Länger als oder passend zur gewünschten Länge
  3. Kürzer als die gewünschte Länge.

Hier ist es:

public static class StringExtensions
{
    public static string Right(this string str, int length)
    {
        return str.Substring(str.Length - length, length);
    }

    public static string MyLast(this string str, int length)
    {
        if (str == null)
            return null;
        else if (str.Length >= length)
            return str.Substring(str.Length - length, length);
        else
            return str;
    }
}

4

Definition:

public static string GetLast(string source, int last)
{
     return last >= source.Length ? source : source.Substring(source.Length - last);
}

Verwendungszweck:

GetLast("string of", 2);

Ergebnis:

von


3

Dies wird für keine Länge Zeichenfolge fehlschlagen.

string mystring = "34234234d124";
string last4 = Regex.Match(mystring, "(?!.{5}).*").Value;
// last4 = "d124"
last4 = Regex.Match("d12", "(?!.{5}).*").Value;
// last4 = "d12"

Dies ist wahrscheinlich ein Overkill für die jeweilige Aufgabe, aber wenn eine zusätzliche Validierung erforderlich ist, kann sie möglicherweise dem regulären Ausdruck hinzugefügt werden.

Edit: Ich denke, dieser Regex wäre effizienter:

@".{4}\Z"

5
Auf jeden Fall übertrieben. Ich würde mich dabei an einfache String-Methoden halten.
Tsells

Die zweite Variante gibt keine Zeichenfolge mit drei Buchstaben zurück, wenn sie mit einem Argument aus drei Buchstaben aufgerufen wird. Sie entspricht also nicht Ihrer ersten genialen Version mit negativem Lookahead! :-)
avl_sweden

3

Verwenden Sie ein Generikum Last<T>. Das funktioniert mit JEDEM IEnumerable, einschließlich String.

public static IEnumerable<T> Last<T>(this IEnumerable<T> enumerable, int nLastElements)
{
    int count = Math.Min(enumerable.Count(), nLastElements);
    for (int i = enumerable.Count() - count; i < enumerable.Count(); i++)
    {
        yield return enumerable.ElementAt(i);
    }
}

Und eine spezielle für String:

public static string Right(this string str, int nLastElements)
{
    return new string(str.Last(nLastElements).ToArray());
}

1
Beeindruckend. Overkill. Vielleicht so etwas wie enumerable.Skip (enumerable.Count () - nLastElements)?
Buh Buh

Ich bin mit @BuhBuh nicht einverstanden, dass dies übertrieben ist. Aber ich bevorzuge "Last" gegenüber "Right" als Namen. Ich bin etwas zimperlich, wenn es darum geht, das vorhandene Last of IEnumerable <T> zu überladen. Ich neige auch zu "Skip".
Plausibel leugnbar

Ich mag diese Lösung. Nicht einfach, aber interessant beim Erlernen von IEnumerable.
pKarelian

1

Ich habe einen Code zusammengestellt, der aus verschiedenen Quellen modifiziert wurde, um die gewünschten Ergebnisse zu erzielen und außerdem noch viel mehr zu tun. Ich habe negative int-Werte zugelassen, int-Werte, die die Länge der Zeichenfolge überschreiten, und einen Endindex, der kleiner als der Startindex ist. In diesem letzten Fall gibt die Methode einen Teilstring in umgekehrter Reihenfolge zurück. Es gibt viele Kommentare, aber lassen Sie mich wissen, wenn etwas unklar oder einfach nur verrückt ist. Ich habe damit herumgespielt, um zu sehen, wofür ich es nur verwenden könnte.

    /// <summary>
    /// Returns characters slices from string between two indexes.
    /// 
    /// If start or end are negative, their indexes will be calculated counting 
    /// back from the end of the source string. 
    /// If the end param is less than the start param, the Slice will return a 
    /// substring in reverse order.
    /// 
    /// <param name="source">String the extension method will operate upon.</param>
    /// <param name="startIndex">Starting index, may be negative.</param>
    /// <param name="endIndex">Ending index, may be negative).</param>
    /// </summary>
    public static string Slice(this string source, int startIndex, int endIndex = int.MaxValue)
    {
        // If startIndex or endIndex exceeds the length of the string they will be set 
        // to zero if negative, or source.Length if positive.
        if (source.ExceedsLength(startIndex)) startIndex = startIndex < 0 ? 0 : source.Length;
        if (source.ExceedsLength(endIndex)) endIndex = endIndex < 0 ? 0 : source.Length;

        // Negative values count back from the end of the source string.
        if (startIndex < 0) startIndex = source.Length + startIndex;
        if (endIndex < 0) endIndex = source.Length + endIndex;         

        // Calculate length of characters to slice from string.
        int length = Math.Abs(endIndex - startIndex);
        // If the endIndex is less than the startIndex, return a reversed substring.
        if (endIndex < startIndex) return source.Substring(endIndex, length).Reverse();

        return source.Substring(startIndex, length);
    }

    /// <summary>
    /// Reverses character order in a string.
    /// </summary>
    /// <param name="source"></param>
    /// <returns>string</returns>
    public static string Reverse(this string source)
    {
        char[] charArray = source.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }

    /// <summary>
    /// Verifies that the index is within the range of the string source.
    /// </summary>
    /// <param name="source"></param>
    /// <param name="index"></param>
    /// <returns>bool</returns>
    public static bool ExceedsLength(this string source, int index)
    {
        return Math.Abs(index) > source.Length ? true : false;
    }

Wenn Sie also eine Zeichenfolge wie "Dies ist eine Erweiterungsmethode" haben, sind hier einige Beispiele und Ergebnisse zu erwarten.

var s = "This is an extension method";
// If you want to slice off end characters, just supply a negative startIndex value
// but no endIndex value (or an endIndex value >= to the source string length).
Console.WriteLine(s.Slice(-5));
// Returns "ethod".
Console.WriteLine(s.Slice(-5, 10));
// Results in a startIndex of 22 (counting 5 back from the end).
// Since that is greater than the endIndex of 10, the result is reversed.
// Returns "m noisnetxe"
Console.WriteLine(s.Slice(2, 15));
// Returns "is is an exte"

Hoffentlich ist diese Version für jemanden hilfreich. Es funktioniert wie gewohnt, wenn Sie keine negativen Zahlen verwenden, und bietet Standardeinstellungen für Parameter außerhalb des Bereichs.


1
string var = "12345678";

if (var.Length >= 4)
{
    var = var.substring(var.Length - 4, 4)
}

// result = "5678"

1

Angenommen, Sie möchten die Zeichenfolgen zwischen einer Zeichenfolge, die 10 Zeichen vom letzten Zeichen entfernt ist, und Sie benötigen nur 3 Zeichen.

Sagen wir StreamSelected = "rtsp://72.142.0.230:80/SMIL-CHAN-273/4CIF-273.stream"

Oben muss ich das extrahieren, das "273"ich in der Datenbankabfrage verwenden werde

        //find the length of the string            
        int streamLen=StreamSelected.Length;

        //now remove all characters except the last 10 characters
        string streamLessTen = StreamSelected.Remove(0,(streamLen - 10));   

        //extract the 3 characters using substring starting from index 0
        //show Result is a TextBox (txtStreamSubs) with 
        txtStreamSubs.Text = streamLessTen.Substring(0, 3);

Diese Frage fragt explizit nach den letzten vier Zeichen in der Zeichenfolge. Sie scheinen eine andere Frage zu beantworten, die sich auf das Extrahieren von Dingen aus der Mitte der Zeichenfolge bezieht. Außerdem Substringkönnen Sie bereits einen Startpunkt und eine Länge übergeben, sodass Sie nicht sicher sind, warum Sie dies nicht verwenden würden, anstatt Removezuerst den Anfang zu entfernen.
Chris

0

Update 2020 : C # 8.0 macht dies endlich einfach:

> "C# 8.0 finally makes this easy"[^4..]
"easy"

Auf die gleiche Weise können Sie auch Arrays in Scheiben schneiden, siehe Indizes und Bereiche .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.