System.String tiene decenas de métodos. Esta página trata los que hacen la mayor parte del trabajo en el código real, con las opciones y las trampas que importan. Hay una regla que se aplica a todos: los strings son inmutables, así que cada método devuelve un string nuevo (o un valor) y deja el original sin cambios. s.Trim(); en su propia línea no hace nada; escribe s = s.Trim();.
Split
Split parte un string en un string[] en cada separador:
Salida:
3
apple
banana
cherry
red/green/ blue/yellow
INFO/started/ready
Fíjate en " blue": Split corta exactamente en el separador y conserva los espacios. Dos opciones se ocupan de las limpiezas habituales:
Salida:
5
4
c#|dotnet|linq
key=[Subject] value=[Re: Meeting: Friday]
3
RemoveEmptyEntries descarta las partes de longitud cero, pero no las que solo tienen espacios (" " sobrevivió arriba). .NET 5 añadió StringSplitOptions.TrimEntries, y las dos pueden combinarse: tags.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) da el resultado limpio en una sola llamada. Pasar null como separador divide por cualquier espacio en blanco, que es la forma habitual de dividir un texto en palabras.
Dividir por un solo char (Split(',')) no necesita array. Las sobrecargas que reciben un char más opciones, o un solo string, existen desde .NET Core 2.0; las formas con array usadas arriba funcionan en todas partes, incluidos .NET Framework y Unity.
Replace
Replace sustituye todas las apariciones de un carácter o de un substring:
Salida:
5551234567
555.123.4567
Cats and dogs and CATS
dogs and dogs and dogs
dogs and cats and CATS
too many spaces
La sobrecarga con un argumento StringComparison está disponible en .NET Core 2.0 y posteriores. En .NET Framework, la sustitución sin distinguir mayúsculas se hace con Regex.Replace(text, Regex.Escape(find), replacement, RegexOptions.IgnoreCase). Sustituir por "" es la forma de eliminar caracteres, y encadenar varias llamadas a Replace está bien para un puñado de sustituciones.
Contains, IndexOf, StartsWith y EndsWith
Estos métodos buscan. Contains responde sí o no; IndexOf y LastIndexOf devuelven una posición, o -1 cuando no hay coincidencia; StartsWith y EndsWith comprueban los extremos.
Salida:
True
False
True
True
8
30
28
-1
16
False
True
True
Todos distinguen mayúsculas y minúsculas por defecto. Contains(string, StringComparison) existe en .NET Core 2.1 y posteriores; la forma IndexOf(...) >= 0 funciona en todas las versiones, y por eso aparece en el código antiguo. IndexOfAny(new[] { ',', ';' }) encuentra el primero de varios caracteres.
Una nota sobre la cultura: sin un StringComparison, StartsWith, EndsWith, IndexOf(string) y CompareTo usan reglas que dependen de la cultura, mientras que Contains, Replace e IndexOf(char) comparan de forma ordinal. Pasar de forma explícita StringComparison.Ordinal u OrdinalIgnoreCase elimina la ambigüedad, y los analizadores de código lo recomiendan.
Trim, TrimStart y TrimEnd
Trim quita los espacios en blanco (espacios, tabuladores, saltos de línea) de los dos extremos. TrimStart y TrimEnd quitan de un solo extremo. Si les pasas caracteres, quitan esos en su lugar:
Salida:
[ana@example.com]
[ana@example.com \n]
[ x]
SALE
7
path/to/dir
1,234.50
Trim solo toca los extremos; los espacios de dentro del string se conservan. TrimStart('0') sobre "000" devuelve un string vacío, así que parsea los strings numéricos con int.Parse en lugar de quitar ceros a mano.
ToUpper y ToLower
Salida:
MAYA LOPEZ
maya lopez
MAYA LOPEZ
Coffee
ToUpper y ToLower siguen la cultura actual, así que en turco "i".ToUpper() es una İ mayúscula con punto, no I. Para identificadores, claves y nombres de archivo, usa ToUpperInvariant y ToLowerInvariant. Para comparar, usa un StringComparison en lugar de convertir mayúsculas (consulta strings). Para poner en mayúscula la inicial de cada palabra existe CultureInfo.CurrentCulture.TextInfo.ToTitleCase(text), aunque deja como están las palabras que ya están enteras en mayúsculas.
PadLeft y PadRight
El relleno añade caracteres hasta que el string alcanza un ancho total. Es práctico para la salida de ancho fijo y para rellenar códigos con ceros:
Salida:
000042
[Tea ]
[ Tea]
Too long already
Espresso.. 2.40
Latte..... 3.60
Mocha..... 3.95
La alineación de la interpolación ({name,-10}) hace el mismo trabajo en línea.
Join y Concat
string.Join pone un separador entre los elementos de cualquier colección. string.Concat une sin separador:
Salida:
Ana, Ben, Chloe
1 + 2 + 3
True
2026-09
AnaBenChloe
Ana, Ben and Chloe
Join es la forma correcta de construir una lista delimitada: no hay ningún separador final que quitar, y construye el resultado en una sola pasada. Llama a ToString() sobre cada elemento, así que también funciona con números y objetos.
Reverse, Insert y Remove
No hay ningún método string.Reverse que devuelva un string. Los dos enfoques habituales:
Salida:
desserts
desserts
True
2026/Q3-09
Hello
HelloWorld
word.Reverse() por sí solo devuelve un IEnumerable<char>, no un string; imprimirlo muestra el nombre de un tipo. Los dos métodos invierten unidades de código UTF-16, lo que rompe los caracteres formados por dos unidades (la mayoría de los emoji) y las letras con acentos combinados.
Referencia rápida
| Tarea | Método |
|---|---|
| Dividir en partes | s.Split(','), s.Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries) |
| Sustituir todo | s.Replace("a", "b") |
| Contiene | s.Contains("x"), s.Contains("x", StringComparison.OrdinalIgnoreCase) |
| Posición | s.IndexOf("x"), s.LastIndexOf('x') (-1 si no está) |
| Empieza o termina por | s.StartsWith("x"), s.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase) |
| Quitar espacios de los extremos | s.Trim(), s.TrimStart(), s.TrimEnd() |
| Cambiar mayúsculas | s.ToUpper(), s.ToLowerInvariant() |
| Rellenar hasta un ancho | s.PadLeft(6, '0'), s.PadRight(10) |
| Unir una colección | string.Join(", ", items) |
| Parte de un string | s.Substring(start, length) |
| Insertar o borrar | s.Insert(i, "x"), s.Remove(i, count) |
| Comprobar null o vacío | string.IsNullOrWhiteSpace(s) |
Preguntas frecuentes
¿Cómo divido un string en C#?
text.Split(',') devuelve un string[] con las partes que hay entre las comas. Pasa varios separadores como array (Split(new[] { ',', ';' })), un separador string con Split(new[] { ", " }, StringSplitOptions.None), y StringSplitOptions.RemoveEmptyEntries para descartar las partes vacías que producen los separadores duplicados. .NET 5 añadió StringSplitOptions.TrimEntries para recortar cada parte.
¿Cómo compruebo si un string contiene otro sin distinguir mayúsculas?
En .NET Core 2.1 y posteriores: text.Contains("error", StringComparison.OrdinalIgnoreCase). En .NET Framework, que no tiene esa sobrecarga, usa text.IndexOf("error", StringComparison.OrdinalIgnoreCase) >= 0. Evita text.ToLower().Contains(...), que reserva una copia y puede fallar en algunas culturas.
¿Cambia String.Replace el string original en C#?
No. Los strings son inmutables, así que Replace devuelve un string nuevo con todas las apariciones sustituidas y deja el original como estaba. Escribe s = s.Replace("old", "new");. Sustituye todas las apariciones, no solo la primera; para sustituir solo la primera, encuéntrala con IndexOf y reconstruye el string, o llama a Replace sobre una instancia de Regex con un recuento de 1.
¿Qué devuelve IndexOf si no encuentra el string?
-1. Cualquier resultado de 0 o mayor es la posición, empezando en cero, de la primera coincidencia. Comprueba siempre si es -1 antes de usar el resultado como índice, porque Substring(-1) lanza una excepción y Substring(-1 + 1) devuelve en silencio el string entero. LastIndexOf funciona igual, buscando desde el final.
¿Cómo invierto un string en C#?
Cópialo en un array de char, invierte el array y construye un string nuevo: char[] a = s.ToCharArray(); Array.Reverse(a); string r = new string(a);. Con LINQ, new string(s.Reverse().ToArray()) hace lo mismo. Los dos invierten unidades UTF-16, así que los emoji y los acentos combinados pueden salir revueltos.