W3docs

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");   // false

contains 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");    // -1

indexOf 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://"); // true

Son 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()); // true

Para 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();
EnfoqueDevuelveÚsalo cuando
containsbooleanPertenencia simple, texto literal
indexOfint (posición, o -1)Necesitas saber dónde está la coincidencia
startsWith / endsWithbooleanAnclado al inicio o al final
Pattern.findbooleanPatrones, 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.

java— editable, runs on the server

Qué extraer de la ejecución:

  • contains "brown" imprime true y contains "cat" imprime falsecontains es la prueba booleana directa de pertenencia para texto literal.
  • contains "FOX" imprime false aunque la palabra "fox" esté presente, lo que demuestra que contains es sensible a mayúsculas; la línea normalizada contains "FOX" (ci) imprime true.
  • indexOf "fox" imprime 16, la posición de base cero donde comienza la coincidencia, mientras que indexOf "bird" imprime -1 para indicar "no encontrado" — ese -1 es el centinela contra el que se comprueba.
  • startsWith "The" y endsWith "dog" ambos imprimen true, mostrando las comprobaciones ancladas al inicio y al final de la frase.
  • contains "" imprime true, 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

Práctica

Práctica
¿Qué devuelve text.indexOf('bird') cuando 'bird' no está presente en el string text?
¿Qué devuelve text.indexOf('bird') cuando 'bird' no está presente en el string text?
Was this page helpful?