Substring gibt einen neuen String zurück, der aus einem Teil eines bestehenden besteht. Es gibt zwei Überladungen:
s.Substring(startIndex): vonstartIndexbis zum Ende.s.Substring(startIndex, length):lengthZeichen, beginnend beistartIndex.
Indizes beginnen bei 0, und das zweite Argument ist eine Länge, keine Endposition. Das ist der Unterschied zu substring(start, end) in JavaScript und substring(begin, end) in Java und die Quelle vieler Fehler um ein paar Stellen, wenn Code portiert wird.
Ausgabe:
4271-BLK
SHOE
4271
BLK
0
SHOE-4271-BLK
Wie jede String-Methode verändert Substring das Original nicht; es gibt einen neuen String zurück, also weise das Ergebnis zu.
ArgumentOutOfRangeException und wie du sie vermeidest
Substring wirft ArgumentOutOfRangeException, wenn der angeforderte Bereich nicht in den String passt: ein negativer startIndex, ein startIndex größer als Length, eine negative length oder startIndex + length größer als Length. Anders als bei Python-Slices wird nicht stillschweigend gekürzt.
Ausgabe:
Substring(2, 4) -> "ffee"
Substring(2, 5) -> ArgumentOutOfRangeException
Substring(6) -> ""
Substring(7) -> ArgumentOutOfRangeException
Substring(-1) -> ArgumentOutOfRangeException
Substring(0, 10) -> ArgumentOutOfRangeException
Die übliche Absicherung ist, die Länge mit Math.Min auf den Rest des Strings zu begrenzen:
Ausgabe:
ffee
ea
[]
[]
Substring auf einem null-String aufzurufen wirft NullReferenceException, nicht ArgumentOutOfRangeException. Deshalb prüft die Hilfsmethode zuerst auf null.
Erste und letzte n Zeichen
Ein Präfix oder Suffix zu nehmen ist die häufigste Verwendung von Substring. Beide Varianten werfen, wenn der String kürzer als n ist, daher prüft Produktionscode die Länge:
Ausgabe:
**** 1111
An Unexpecte...
Hi
Hi
Wenn du den Anfang des Strings loswerden willst, reicht Substring(n) allein: "#FF8800".Substring(1) ist "FF8800". Das verwandte Remove(start, count) macht das Gegenteil von Substring: Es gibt den String ohne diesen Bereich zurück.
Substring mit IndexOf
Die meisten echten Teilstrings werden gesucht, nicht abgezählt. IndexOf gibt die Position eines Zeichens oder Strings zurück (oder -1, wenn er nicht vorkommt), und LastIndexOf sucht vom Ende her. Kombiniere sie mit Substring, um Text an einem Trennzeichen zu zerschneiden:
Ausgabe:
maya.lopez
example.com
pdf
report.final.v2
WARN
Disk almost full
Die Arithmetik folgt einer Regel: Um den Text zwischen den Positionen a und b zu nehmen (beide ausgeschlossen), ist der Start a + 1 und die Länge b - a - 1.
Die Gefahr ist, dass IndexOf -1 zurückgibt. email.Substring(0, -1) wirft, und schlimmer noch, email.Substring(-1 + 1) gibt stillschweigend den ganzen String zurück. Prüfe immer:
Ausgabe:
shop.io
(none)
Split als Alternative
Wenn ein String eine Liste von Feldern mit Trennzeichen ist, ist Split einfacher als eine Kette von Aufrufen von IndexOf und Substring, und es gibt keine Indexarithmetik, bei der man sich vertun kann:
Ausgabe:
Ana Silva
Porto
maya.lopez
beach.jpg
Split allokiert ein Array plus einen String pro Feld. Für einen einzelnen Schnitt in einer heißen Schleife sind IndexOf und Substring daher günstiger. Überall sonst gewinnt die Lesbarkeit. Weitere Optionen (mehrere Trennzeichen, leere Einträge entfernen, eine Höchstanzahl) findest du unter String-Methoden. Für Muster wie „die Ziffern nach ID:“ ist ein regulärer Ausdruck meist das klarste Werkzeug.
Der Bereichsoperator (ab C# 8)
C# 8 hat Index- und Bereichssyntax eingeführt, die mit Strings und Arrays funktioniert. ^n bedeutet „n vom Ende“, und a..b ist der Bereich von a bis ausschließlich b, die zweite Zahl ist also ein Endindex, keine Länge:
// C# 8 and later
string sku = "SHOE-4271-BLK";
string first4 = sku[..4]; // "SHOE" same as Substring(0, 4)
string middle = sku[5..9]; // "4271" same as Substring(5, 4)
string last3 = sku[^3..]; // "BLK" same as Substring(sku.Length - 3)
string noEnds = sku[1..^1]; // "HOE-4271-BL" drop first and last
char lastChar = sku[^1]; // 'K'
Bei einem String wird ein Bereich zu einem Aufruf von Substring kompiliert, er allokiert also einen neuen String und wirft ArgumentOutOfRangeException in denselben Fällen außerhalb der Grenzen. Was du nimmst, ist Stilfrage; Bereiche lesen sich besser, wenn beide Enden von verschiedenen Seiten gemessen werden ([1..^1]).
Teilstrings ohne Kopie: Span
Jeder Aufruf von Substring allokiert einen neuen String. In performancekritischem Parsing-Code (große Dateien lesen, viele Anfragen verarbeiten) bieten .NET Core 2.1 und neuer ReadOnlySpan<char>, eine Sicht auf einen Teil des ursprünglichen Strings ohne Kopie:
ReadOnlySpan<char> line = "2026-09-24,42.50,EUR".AsSpan();
ReadOnlySpan<char> amount = line.Slice(11, 5); // "42.50", no allocation
decimal value = decimal.Parse(amount, provider: CultureInfo.InvariantCulture);
Spans können nicht in Feldern normaler Klassen gespeichert oder über await hinweg verwendet werden, sie gehören also in engen, synchronen Code. Für typischen Anwendungscode ist Substring das richtige Werkzeug.
Häufige Fehler
- Einen Endindex als Länge übergeben.
s.Substring(2, 5)bedeutet fünf Zeichen ab Index 2, nicht „Index 2 bis 5“. Um den Text von Indexabis ausschließlich Indexbzu nehmen, ist die Längeb - a. IndexOfnicht auf -1 prüfen. Entweder eine Exception oder, mit+ 1, versehentlich der ganze String.- Annehmen, dass kurze Strings lang genug sind. Ein Name, ein Code oder eine Zeile aus einer Datei kann kürzer sein als erwartet. Begrenze mit
Math.Minoder prüfeLength. - Das Ergebnis verwerfen.
s.Substring(1);allein in einer Zeile bewirkt nichts Nützliches.
Häufig gestellte Fragen
Wie funktioniert Substring in C#?
s.Substring(start) gibt die Zeichen ab Index start bis zum Ende zurück; s.Substring(start, length) gibt length Zeichen ab start zurück. Indizes beginnen bei 0, und das zweite Argument ist eine Länge, kein Endindex: "Hello".Substring(1, 3) ist "ell". Der ursprüngliche String wird nicht verändert.
Warum wirft Substring eine ArgumentOutOfRangeException?
Weil start negativ oder größer als die Länge des Strings ist oder start + length über das Ende hinausgeht. Die häufigste Ursache ist eine Länge, die für einen längeren String berechnet wurde, oder ein IndexOf-Ergebnis von -1, das als Start verwendet wird. Begrenze die Länge mit Math.Min(length, s.Length - start) und prüfe IndexOf-Ergebnisse, bevor du sie verwendest.
Wie bekomme ich in C# die letzten n Zeichen eines Strings?
s.Substring(s.Length - n) gibt die letzten n Zeichen zurück, sofern n <= s.Length gilt. Sicher auch für kurze Strings ist s.Length <= n ? s : s.Substring(s.Length - n). Ab C# 8 kannst du auch s[^n..] schreiben, das auf dieselbe Weise wirft, wenn n zu groß ist.
Wie bekomme ich in C# den Teilstring zwischen zwei Zeichen?
Finde beide Positionen mit IndexOf und nimm dann den Teil dazwischen: int start = s.IndexOf('(') + 1; int end = s.IndexOf(')', start); string inside = s.Substring(start, end - start);. Prüfe, ob jedes IndexOf etwas gefunden hat (nicht -1), bevor du Substring aufrufst. Für komplexe Muster ist ein regulärer Ausdruck klarer.
Ist Substring in C# nullbasiert?
Ja. Das erste Zeichen steht an Index 0, das letzte an Length - 1. Substring(0, 3) gibt die ersten drei Zeichen zurück. Length selbst als Start zu übergeben ist erlaubt und liefert einen leeren String.