Menu

C# 문자열 메서드: Split, Replace, Contains, IndexOf, Trim, Join 등

C#에서 매일 쓰는 String 메서드: 여러 구분자와 옵션을 쓰는 Split, Replace, Contains와 대소문자 무시 검색, IndexOf와 LastIndexOf, StartsWith와 EndsWith, Trim, ToUpper와 ToLower, PadLeft, Join, Concat, 문자열 뒤집기를 알아봅니다.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

System.String에는 수십 개의 메서드가 있습니다. 이 페이지는 실제 코드에서 대부분의 일을 하는 메서드들을 중요한 옵션, 함정과 함께 다룹니다. 모든 메서드에 적용되는 규칙이 하나 있습니다. 문자열은 불변이므로 모든 메서드는 원본을 그대로 두고 새 문자열(또는 값)을 반환합니다. 한 줄에 단독으로 쓴 s.Trim();은 아무것도 하지 않습니다. s = s.Trim();이라고 쓰세요.

Split

Split은 구분자마다 문자열을 잘라 string[]로 만듭니다:

출력:

3
apple
banana
cherry
red/green/ blue/yellow
INFO/started/ready

" blue"에 주목하세요. Split은 구분자에서 정확히 자르고 공백은 그대로 둡니다. 흔한 정리 작업은 두 옵션으로 처리합니다:

출력:

5
4
c#|dotnet|linq
key=[Subject] value=[Re: Meeting: Friday]
3

RemoveEmptyEntries는 길이가 0인 부분은 버리지만 공백만 있는 부분은 버리지 않습니다(위에서 " "가 남았습니다). .NET 5는 StringSplitOptions.TrimEntries를 추가했고 두 옵션을 함께 쓸 수 있습니다. tags.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)는 한 번의 호출로 깔끔한 결과를 줍니다. 구분자로 null을 넘기면 모든 공백 문자에서 자르며, 텍스트를 단어로 나누는 흔한 방법입니다.

char 하나로 자를 때(Split(','))는 배열이 필요 없습니다. char와 옵션을 받는 오버로드나 string 하나를 받는 오버로드는 .NET Core 2.0부터 있습니다. 위에서 쓴 배열 형태는 .NET Framework와 Unity를 포함해 어디서나 동작합니다.

Replace

Replace는 문자나 부분 문자열의 모든 일치 항목을 바꿉니다:

출력:

5551234567
555.123.4567
Cats and dogs and CATS
dogs and dogs and dogs
dogs and cats and CATS
too many spaces

StringComparison 인수를 받는 오버로드는 .NET Core 2.0 이상에서 쓸 수 있습니다. .NET Framework에서는 Regex.Replace(text, Regex.Escape(find), replacement, RegexOptions.IgnoreCase)로 대소문자를 무시하고 바꿉니다. ""로 바꾸는 것이 문자를 지우는 방법이며, 몇 개 정도의 치환이라면 Replace 호출을 연결해도 괜찮습니다.

Contains, IndexOf, StartsWith, EndsWith

이 메서드들은 검색합니다. Contains는 예 또는 아니요로 답하고, IndexOf와 LastIndexOf는 위치를 반환하며 일치 항목이 없으면 -1을 반환하고, StartsWith와 EndsWith는 양 끝을 검사합니다.

출력:

True
False
True
True
8
30
28
-1
16
False
True
True

모두 기본적으로 대소문자를 구분합니다. Contains(string, StringComparison)은 .NET Core 2.1 이상에 있고, IndexOf(...) >= 0 형태는 모든 버전에서 동작하므로 예전 코드에서 자주 보입니다. IndexOfAny(new[] { ',', ';' })는 여러 문자 중 처음 나오는 것을 찾습니다.

문화권에 관한 참고: StringComparison 없이 쓰면 StartsWith, EndsWith, IndexOf(string), CompareTo는 문화권 규칙을 쓰고, Contains, Replace, IndexOf(char)는 서수 비교를 합니다. StringComparison.Ordinal이나 OrdinalIgnoreCase를 명시적으로 넘기면 모호함이 사라지며, 코드 분석기도 이를 권장합니다.

Trim, TrimStart, TrimEnd

Trim은 양 끝의 공백 문자(스페이스, 탭, 줄바꿈)를 제거합니다. TrimStart와 TrimEnd는 한쪽 끝에서만 제거합니다. 문자를 넘기면 공백 대신 그 문자들을 제거합니다:

출력:

[ana@example.com]
[ana@example.com \n]
[  x]
SALE
7
path/to/dir
1,234.50

Trim은 양 끝만 건드리고 문자열 안의 공백은 그대로 둡니다. "000"에 TrimStart('0')를 쓰면 빈 문자열이 되므로, 숫자 문자열은 직접 0을 벗기지 말고 int.Parse로 파싱하세요.

ToUpper와 ToLower

출력:

MAYA LOPEZ
maya lopez
MAYA LOPEZ
Coffee

ToUpper와 ToLower는 현재 문화권을 따르므로 터키어에서 "i".ToUpper()는 I가 아니라 점이 있는 대문자 İ입니다. 식별자, 키, 파일 이름에는 ToUpperInvariant와 ToLowerInvariant를 쓰세요. 비교할 때는 대소문자를 변환하지 말고 StringComparison을 쓰세요(문자열 참고). 모든 단어의 첫 글자를 대문자로 만드는 CultureInfo.CurrentCulture.TextInfo.ToTitleCase(text)도 있지만, 이미 전부 대문자인 단어는 그대로 둡니다.

PadLeft와 PadRight

패딩은 문자열이 전체 너비에 도달할 때까지 문자를 추가합니다. 고정 너비 출력과 코드의 0 채우기에 편리합니다:

출력:

000042
[Tea     ]
[     Tea]
Too long already
Espresso..  2.40
Latte.....  3.60
Mocha.....  3.95

보간의 정렬({name,-10})도 같은 일을 줄 안에서 합니다.

Join과 Concat

string.Join은 모든 컬렉션의 요소 사이에 구분자를 넣습니다. string.Concat은 구분자 없이 이어 붙입니다:

출력:

Ana, Ben, Chloe
1 + 2 + 3
True
2026-09
AnaBenChloe
Ana, Ben and Chloe

구분자로 나뉜 목록을 만드는 올바른 방법은 Join입니다. 지워야 할 마지막 구분자가 없고 결과를 한 번에 만듭니다. 각 요소에 ToString()을 호출하므로 숫자와 객체에도 동작합니다.

Reverse, Insert, Remove

문자열을 반환하는 string.Reverse 메서드는 없습니다. 보통 쓰는 두 가지 방법입니다:

출력:

desserts
desserts
True
2026/Q3-09
Hello
HelloWorld

word.Reverse()만 쓰면 문자열이 아니라 IEnumerable<char>를 반환하므로, 출력하면 타입 이름이 나옵니다. 두 방법 모두 UTF-16 코드 단위를 뒤집으므로 두 단위로 이루어진 문자(대부분의 이모지)와 결합 악센트가 붙은 글자가 깨집니다.

빠른 참조

작업메서드
여러 부분으로 나누기s.Split(','), s.Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries)
모두 바꾸기s.Replace("a", "b")
포함 여부s.Contains("x"), s.Contains("x", StringComparison.OrdinalIgnoreCase)
위치s.IndexOf("x"), s.LastIndexOf('x')(없으면 -1)
시작 또는 끝 검사s.StartsWith("x"), s.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase)
양 끝 공백 제거s.Trim(), s.TrimStart(), s.TrimEnd()
대소문자 변경s.ToUpper(), s.ToLowerInvariant()
너비에 맞춰 채우기s.PadLeft(6, '0'), s.PadRight(10)
컬렉션 합치기string.Join(", ", items)
문자열 일부s.Substring(start, length)
삽입 또는 삭제s.Insert(i, "x"), s.Remove(i, count)
null 또는 공백 검사string.IsNullOrWhiteSpace(s)

자주 묻는 질문

C#에서 문자열은 어떻게 나누나요?

text.Split(',')는 쉼표 사이의 부분들을 string[]로 반환합니다. 여러 구분자는 배열로 넘기고(Split(new[] { ',', ';' })), 문자열 구분자는 Split(new[] { ", " }, StringSplitOptions.None)으로 넘기며, 구분자가 겹쳐서 생긴 빈 부분을 버리려면 StringSplitOptions.RemoveEmptyEntries를 넘기세요. .NET 5는 각 부분을 trim하는 StringSplitOptions.TrimEntries를 추가했습니다.

대소문자를 무시하고 문자열에 다른 문자열이 들어 있는지 어떻게 확인하나요?

.NET Core 2.1 이상에서는 text.Contains("error", StringComparison.OrdinalIgnoreCase)입니다. 이 오버로드가 없는 .NET Framework에서는 text.IndexOf("error", StringComparison.OrdinalIgnoreCase) >= 0을 쓰세요. text.ToLower().Contains(...)는 복사본을 할당하고 일부 문화권에서 오동작할 수 있으므로 피하세요.

C#의 String.Replace는 원본 문자열을 바꾸나요?

아니요. 문자열은 불변이므로 Replace는 모든 일치 항목을 바꾼 새 문자열을 반환하고 원본은 그대로 둡니다. s = s.Replace("old", "new");라고 쓰세요. 첫 번째만이 아니라 모든 일치 항목을 바꿉니다. 첫 번째만 바꾸려면 IndexOf로 찾아 문자열을 다시 만들거나, Regex 인스턴스의 Replace를 개수 1로 호출하세요.

IndexOf는 문자열을 찾지 못하면 무엇을 반환하나요?

-1입니다. 0 이상의 결과는 첫 번째 일치 항목의 0부터 시작하는 위치입니다. Substring(-1)은 예외를 던지고 Substring(-1 + 1)은 조용히 문자열 전체를 반환하므로, 결과를 인덱스로 쓰기 전에 항상 -1인지 확인하세요. LastIndexOf도 끝에서부터 찾는다는 점만 빼면 똑같이 동작합니다.

C#에서 문자열을 뒤집으려면 어떻게 하나요?

char 배열로 복사하고, 배열을 뒤집고, 새 문자열을 만듭니다: char[] a = s.ToCharArray(); Array.Reverse(a); string r = new string(a);. LINQ로는 new string(s.Reverse().ToArray())가 같은 일을 합니다. 둘 다 UTF-16 단위를 뒤집으므로 이모지와 결합 악센트는 깨질 수 있습니다.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기