Cómo comprobar si una cadena contiene una subcadena en Java
Comprueba subcadenas en Java con contains, indexOf, startsWith, endsWith y expresiones regulares.
Comprobar si un String aparece dentro de otro es una de las tareas de texto más comunes en Java. La herramienta adecuada depende de lo que realmente necesites: una respuesta booleana de sí/no, la posición de la coincidencia, una comprobación anclada al inicio o al final, o un patrón flexible. Este capítulo recorre cada enfoque idiomático y cuándo utilizarlo.
La opción por defecto: String.contains
Cuando solo necesitas un boolean — "¿está este fragmento ahí o no?" — contains es la opción más clara:
String text = "The quick brown fox";
boolean hasFox = text.contains("fox"); // true
boolean hasCat = text.contains("cat"); // falsecontains acepta cualquier CharSequence (es decir, String, StringBuilder, etc.) y devuelve true si el argumento aparece en cualquier parte del string. Es sensible a mayúsculas y minúsculas: text.contains("FOX") es false. Un caso límite que conviene recordar: la cadena vacía está contenida en cualquier string, por lo que text.contains("") siempre es true.
Cuando necesitas la posición: indexOf
contains está implementado internamente sobre indexOf. Si necesitas saber dónde empieza una coincidencia (o quieres buscar repeticiones), llama directamente a indexOf:
String text = "The quick brown fox";
int at = text.indexOf("brown"); // 10
int no = text.indexOf("bird"); // -1indexOf devuelve el índice de base cero de la primera coincidencia, o -1 cuando la subcadena no está presente. El idioma clásico de pertenencia es text.indexOf("brown") >= 0, que equivale a contains pero también te da la posición sin coste adicional. También existe lastIndexOf para buscar desde el final, y una sobrecarga que acepta un desplazamiento inicial para encontrar coincidencias posteriores en un bucle.
Comprobaciones ancladas: startsWith y endsWith
Si te interesa específicamente el inicio o el final de un string — extensiones de archivo, prefijos de URL, esquemas de protocolo — startsWith y endsWith expresan la intención directamente y resultan más legibles que el uso de subcadenas:
String file = "report.pdf";
boolean isPdf = file.endsWith(".pdf"); // true
boolean isHttp = "https://w3docs.com".startsWith("https://"); // trueSon más rápidos y claros que indexOf(prefix) == 0, porque dejan de comparar en cuanto un carácter difiere y nunca recorren todo el string.
Búsqueda sin distinción de mayúsculas y coincidencias de patrones
contains no tiene una sobrecarga sin distinción de mayúsculas. La solución más sencilla es normalizar ambos lados:
boolean ci = text.toLowerCase().contains("FOX".toLowerCase()); // truePara algo más que un fragmento literal — alternativas, comodines, límites de palabra — utiliza una expresión regular. Pattern.compile(...).matcher(text).find() devuelve true si el patrón coincide en cualquier parte, y CASE_INSENSITIVE gestiona las mayúsculas sin crear copias en minúsculas:
import java.util.regex.Pattern;
boolean found = Pattern.compile("fox", Pattern.CASE_INSENSITIVE)
.matcher(text).find();| Enfoque | Devuelve | Úsalo cuando |
|---|---|---|
contains | boolean | Pertenencia simple, texto literal |
indexOf | int (posición, o -1) | Necesitas saber dónde está la coincidencia |
startsWith / endsWith | boolean | Anclado al inicio o al final |
Pattern.find | boolean | Patrones, alternativas, sin distinción de mayúsculas |
Un ejemplo práctico
Este programa ejecuta los cuatro enfoques en paralelo sobre una misma frase, incluyendo el problema de la sensibilidad a mayúsculas y el caso límite de la cadena vacía.
Qué extraer de la ejecución:
contains "brown"imprimetrueycontains "cat"imprimefalse—containses la prueba booleana directa de pertenencia para texto literal.contains "FOX"imprimefalseaunque la palabra "fox" esté presente, lo que demuestra quecontainses sensible a mayúsculas; la línea normalizadacontains "FOX" (ci)imprimetrue.indexOf "fox"imprime16, la posición de base cero donde comienza la coincidencia, mientras queindexOf "bird"imprime-1para indicar "no encontrado" — ese-1es el centinela contra el que se comprueba.startsWith "The"yendsWith "dog"ambos imprimentrue, mostrando las comprobaciones ancladas al inicio y al final de la frase.contains ""imprimetrue, el recordatorio de que todo string contiene la cadena vacía — protégete contra entradas vacías si eso pudiera ser un error.
Temas relacionados
- Java Strings — la base de todos los métodos de esta página.
- Java String Methods — la referencia completa de
contains,indexOf,startsWithy compañía. - Cómo comparar cadenas en Java — igualdad y orden, el complemento natural de la pertenencia.
- Java Regex: Pattern and Matcher — profundiza en el enfoque basado en patrones mostrado anteriormente.