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?

KentZhou
quelle
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);
Armen Tsirunyan
quelle
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);
Stecya
quelle
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);
der Stern
quelle
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);
RJ-Programmierer
quelle
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)
Cem
quelle
26

Die Verwendung von Teilzeichenfolgen ist eigentlich recht kurz und lesbar:

 var result = mystring.Substring(mystring.Length - Math.Min(4, mystring.Length));
 // result == "d124"
dtb
quelle
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.

Andre Luus
quelle
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.

Amit Kumawat
quelle
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);
Anees Deen
quelle
7
mystring = mystring.Length > 4 ? mystring.Substring(mystring.Length - 4, 4) : mystring;
Michael Burggraf
quelle
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);
Daniel DiPaolo
quelle
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;
    }
}
Marcelo Finki
quelle
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

Erçin Dedeoğlu
quelle
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"
Agent-j
quelle
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());
}
Adriano Carneiro
quelle
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.

irisch
quelle
1
string var = "12345678";

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

// result = "5678"
Eidan
quelle
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);
Shinn_33
quelle
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 .

Oberst Panik
quelle