System.String ma dziesiątki metod. Ta strona omawia te, które w prawdziwym kodzie wykonują większość pracy, razem z opcjami i pułapkami, które mają znaczenie. Jedna zasada dotyczy wszystkich: stringi są niemutowalne, więc każda metoda zwraca nowy string (albo wartość), a oryginał zostaje bez zmian. Samo s.Trim(); w osobnej linii nic nie robi; pisz s = s.Trim();.
Split
Split dzieli string na string[] w miejscu każdego separatora:
Wynik:
3
apple
banana
cherry
red/green/ blue/yellow
INFO/started/ready
Zwróć uwagę na " blue": Split tnie dokładnie na separatorze i zachowuje spacje. Dwie opcje załatwiają typowe porządki:
Wynik:
5
4
c#|dotnet|linq
key=[Subject] value=[Re: Meeting: Friday]
3
RemoveEmptyEntries usuwa fragmenty o długości zero, ale nie te złożone z samych spacji (" " przetrwało powyżej). .NET 5 dodał StringSplitOptions.TrimEntries i obie opcje można łączyć: tags.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) daje czysty wynik w jednym wywołaniu. Przekazanie null jako separatora dzieli po dowolnym białym znaku, co jest typowym sposobem na podział tekstu na słowa.
Podział po pojedynczym char (Split(',')) nie wymaga tablicy. Przeciążenia przyjmujące char z opcjami albo pojedynczy string istnieją od .NET Core 2.0; formy z tablicą użyte powyżej działają wszędzie, także w .NET Framework i Unity.
Replace
Replace zastępuje każde wystąpienie znaku lub podciągu:
Wynik:
5551234567
555.123.4567
Cats and dogs and CATS
dogs and dogs and dogs
dogs and cats and CATS
too many spaces
Przeciążenie z argumentem StringComparison jest dostępne w .NET Core 2.0 i nowszych. W .NET Framework zamianę bez rozróżniania wielkości liter robi się przez Regex.Replace(text, Regex.Escape(find), replacement, RegexOptions.IgnoreCase). Zamiana na "" to sposób na usuwanie znaków, a łańcuch kilku wywołań Replace sprawdza się przy kilku podstawieniach.
Contains, IndexOf, StartsWith i EndsWith
Te metody wyszukują. Contains odpowiada tak lub nie; IndexOf i LastIndexOf zwracają pozycję albo -1, gdy nie ma dopasowania; StartsWith i EndsWith sprawdzają początek i koniec.
Wynik:
True
False
True
True
8
30
28
-1
16
False
True
True
Domyślnie wszystkie rozróżniają wielkość liter. Contains(string, StringComparison) istnieje w .NET Core 2.1 i nowszych; forma IndexOf(...) >= 0 działa w każdej wersji, dlatego widać ją w starszym kodzie. IndexOfAny(new[] { ',', ';' }) znajduje pierwszy z kilku znaków.
Uwaga o kulturze: bez StringComparison metody StartsWith, EndsWith, IndexOf(string) i CompareTo stosują reguły zależne od kultury, a Contains, Replace i IndexOf(char) porównują porządkowo. Jawne przekazanie StringComparison.Ordinal lub OrdinalIgnoreCase usuwa tę niejednoznaczność i zalecają to analizatory kodu.
Trim, TrimStart i TrimEnd
Trim usuwa białe znaki (spacje, tabulatory, nowe linie) z obu końców. TrimStart i TrimEnd usuwają je z jednego końca. Jeśli podasz znaki, usuwają właśnie je:
Wynik:
[ana@example.com]
[ana@example.com \n]
[ x]
SALE
7
path/to/dir
1,234.50
Trim dotyka tylko końców; spacje w środku stringa zostają. TrimStart('0') na "000" zwraca pusty string, więc liczby zapisane jako tekst parsuj przez int.Parse, zamiast ręcznie obcinać zera.
ToUpper i ToLower
Wynik:
MAYA LOPEZ
maya lopez
MAYA LOPEZ
Coffee
ToUpper i ToLower działają według bieżącej kultury, więc po turecku "i".ToUpper() to wielkie İ z kropką, a nie I. Dla identyfikatorów, kluczy i nazw plików używaj ToUpperInvariant i ToLowerInvariant. Do porównywania użyj StringComparison zamiast w ogóle zmieniać wielkość liter (zobacz stringi). Do zamiany pierwszej litery każdego słowa na wielką służy CultureInfo.CurrentCulture.TextInfo.ToTitleCase(text), choć zostawia bez zmian słowa zapisane w całości wielkimi literami.
PadLeft i PadRight
Dopełnianie dodaje znaki, aż string osiągnie łączną szerokość. Przydaje się przy wydruku o stałej szerokości i przy uzupełnianiu kodów zerami:
Wynik:
000042
[Tea ]
[ Tea]
Too long already
Espresso.. 2.40
Latte..... 3.60
Mocha..... 3.95
Wyrównanie w interpolacji ({name,-10}) robi to samo w miejscu.
Join i Concat
string.Join wstawia separator między elementy dowolnej kolekcji. string.Concat łączy bez separatora:
Wynik:
Ana, Ben, Chloe
1 + 2 + 3
True
2026-09
AnaBenChloe
Ana, Ben and Chloe
Join to właściwy sposób na zbudowanie listy z separatorami: nie trzeba usuwać separatora na końcu, a wynik powstaje w jednym przebiegu. Wywołuje ToString() na każdym elemencie, więc działa też z liczbami i obiektami.
Reverse, Insert i Remove
Nie ma metody string.Reverse, która zwraca string. Dwa typowe podejścia:
Wynik:
desserts
desserts
True
2026/Q3-09
Hello
HelloWorld
Samo word.Reverse() zwraca IEnumerable<char>, a nie string; wypisanie go pokazuje nazwę typu. Obie metody odwracają jednostki kodowe UTF-16, co psuje znaki złożone z dwóch jednostek (większość emoji) i litery z łączonymi akcentami.
Ściąga
| Zadanie | Metoda |
|---|---|
| Podział na części | s.Split(','), s.Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries) |
| Zamiana wszystkich | s.Replace("a", "b") |
| Zawiera | s.Contains("x"), s.Contains("x", StringComparison.OrdinalIgnoreCase) |
| Pozycja | s.IndexOf("x"), s.LastIndexOf('x') (-1, jeśli brak) |
| Zaczyna się lub kończy na | s.StartsWith("x"), s.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase) |
| Usunięcie białych znaków z końców | s.Trim(), s.TrimStart(), s.TrimEnd() |
| Zmiana wielkości liter | s.ToUpper(), s.ToLowerInvariant() |
| Dopełnienie do szerokości | s.PadLeft(6, '0'), s.PadRight(10) |
| Złączenie kolekcji | string.Join(", ", items) |
| Fragment stringa | s.Substring(start, length) |
| Wstawienie lub usunięcie | s.Insert(i, "x"), s.Remove(i, count) |
| Sprawdzenie null lub pustego | string.IsNullOrWhiteSpace(s) |
Najczęściej zadawane pytania
Jak podzielić string w C#?
text.Split(',') zwraca string[] z fragmentami między przecinkami. Kilka separatorów przekaż jako tablicę (Split(new[] { ',', ';' })), separator będący stringiem przez Split(new[] { ", " }, StringSplitOptions.None), a StringSplitOptions.RemoveEmptyEntries pomija puste fragmenty powstałe z podwójnych separatorów. .NET 5 dodał StringSplitOptions.TrimEntries, które przycina każdy fragment.
Jak sprawdzić, czy string zawiera inny string, bez rozróżniania wielkości liter?
Na .NET Core 2.1 i nowszych: text.Contains("error", StringComparison.OrdinalIgnoreCase). Na .NET Framework, który nie ma tego przeciążenia, użyj text.IndexOf("error", StringComparison.OrdinalIgnoreCase) >= 0. Unikaj text.ToLower().Contains(...): tworzy kopię i w niektórych kulturach może działać nieprawidłowo.
Czy String.Replace zmienia oryginalny string w C#?
Nie. Stringi są niemutowalne, więc Replace zwraca nowy string z zastąpionymi wszystkimi wystąpieniami, a oryginał zostaje bez zmian. Pisz s = s.Replace("old", "new");. Metoda zastępuje wszystkie wystąpienia, nie tylko pierwsze; żeby zastąpić tylko pierwsze, znajdź je przez IndexOf i zbuduj string od nowa albo wywołaj Replace na instancji Regex z licznikiem 1.
Co zwraca IndexOf, jeśli nie znajdzie stringa?
-1. Każdy wynik równy 0 lub większy to liczona od zera pozycja pierwszego dopasowania. Zawsze sprawdzaj -1, zanim użyjesz wyniku jako indeksu, bo Substring(-1) rzuca wyjątek, a Substring(-1 + 1) po cichu zwraca cały string. LastIndexOf działa tak samo, ale szuka od końca.
Jak odwrócić string w C#?
Skopiuj go do tablicy znaków, odwróć tablicę i zbuduj nowy string: char[] a = s.ToCharArray(); Array.Reverse(a); string r = new string(a);. Z LINQ to samo robi new string(s.Reverse().ToArray()). Oba sposoby odwracają jednostki UTF-16, więc emoji i łączone akcenty mogą się rozsypać.