W3docs

Cómo contar palabras en una cadena en Java

Cuenta el número de palabras en una cadena Java usando trim y split con espacios en blanco, un matcher de regex, y evitando el split ingenuo.

Contar las palabras de una cadena parece trivial — dividir por espacios y contar las partes — pero la versión ingenua falla en cuanto la entrada tiene espacios iniciales, finales o repetidos. Este capítulo muestra las formas idiomáticas de contar palabras en Java, los casos límite que confunden a la gente y qué enfoque usar. Se basa en los fundamentos de Java Strings y String split and join.

Dividir por espacios en blanco (la opción predeterminada fiable)

La receta estándar es recortar la cadena y luego dividirla por uno o más caracteres de espacio en blanco con la regex \s+:

String text = "  The quick   brown fox  ";
String trimmed = text.trim();
int words = trimmed.isEmpty() ? 0 : trimmed.split("\\s+").length;
System.out.println(words); // 4

Dos detalles hacen que esto sea correcto. El trim() elimina los espacios iniciales y finales, porque split("\\s+") sobre una cadena que comienza con espacios en blanco produce un elemento vacío al inicio. El control con isEmpty() maneja la entrada en blanco: dividir "" devuelve un array de longitud 1, no 0, por lo que sin esta comprobación una cadena en blanco reportaría erróneamente una palabra.

El \\s es un literal de cadena Java para la regex \s, que coincide con espacios, tabulaciones y saltos de línea. El + significa "uno o más", de modo que cualquier secuencia de espacios en blanco cuenta como un único separador.

Evitar el split ingenuo con un solo espacio

Es tentador escribir text.split(" ").length, pero eso divide en exactamente un espacio y falla con entradas del mundo real:

String text = "  The quick   brown fox  ";
System.out.println(text.split(" ").length); // 8, not 4

Los dos espacios iniciales producen dos elementos vacíos al comienzo, y cada secuencia de tres espacios internos añade más — por lo que el array es ["", "", "The", "quick", "", "", "brown", "fox"], ocho elementos en lugar de cuatro. (El método split de Java descarta los strings vacíos al final, razón por la que los dos espacios finales no añaden nada.) Cada espacio doble y cada espacio inicial infla el contador. Dividir por " " solo es seguro cuando ya se sabe que la entrada es una línea delimitada por un único espacio sin espaciado extra — lo cual rara vez está garantizado.

Contar tokens con un matcher de regex

En lugar de dividir, puedes hacer coincidir los tokens de palabras directamente y contar las coincidencias. Esto evita por completo el problema de los elementos vacíos:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

Matcher m = Pattern.compile("\\w+").matcher(text);
int count = 0;
while (m.find()) {
    count++;
}

\w+ coincide con secuencias de caracteres de palabra (letras, dígitos, guión bajo). Como busca palabras en lugar de separadores, los espacios en blanco iniciales, finales y repetidos son irrelevantes — no se necesita ningún control. La contrapartida es que \w excluye la puntuación, por lo que "well-known" con guión cuenta como dos tokens. Elige el patrón que se ajuste a tu definición de "palabra".

Si necesitas tokenizar un documento más largo o un flujo en lugar de una sola línea, el capítulo Java StringTokenizer cubre una clase diseñada específicamente para dividir texto en tokens.

EnfoqueManeja espacios extra/límiteSeguro con string vacíoNota
split(" ")NoNoFalla con espacios repetidos
trim().split("\\s+")Con control isEmpty()La opción predeterminada
Matcher Pattern \w+Sí (cuenta 0)Divide en puntuación

Un ejemplo completo y funcional

java— editable, runs on the server

Lo que se puede extraer de la ejecución:

  • Naive split length: 8 demuestra que split(" ") sobreestima considerablemente porque cada espacio inicial y cada espacio dentro de una secuencia genera un elemento vacío extra en el array.
  • Whitespace split: 4 muestra que trim().split("\\s+") colapsa cada secuencia de espacios en blanco y devuelve el conteo correcto.
  • Regex matcher: 4 confirma que el matcher \w+ llega al mismo resultado sin necesidad de recortar ni de controles.
  • Blank input words: 0 demuestra por qué importa el control isEmpty() — sin él, una entrada en blanco reportaría erróneamente una palabra.
  • Los tres métodos correctos coinciden en 4, por lo que la diferencia entre ellos es la robustez y la definición de "palabra", no el resultado con una entrada limpia.

Práctica

Práctica
¿Por qué dividir con un solo espacio sobreestima las palabras cuando la cadena tiene espacios repetidos o iniciales?
¿Por qué dividir con un solo espacio sobreestima las palabras cuando la cadena tiene espacios repetidos o iniciales?
Was this page helpful?