Como Contar Palavras em uma String em Java
Conte palavras em uma string Java usando trim e split com whitespace, um regex matcher e evitando o split ingênuo em espaço único.
Contar as palavras em uma string parece trivial — dividir por espaços e contar as partes — mas a versão ingênua falha no momento em que a entrada tem espaços iniciais, finais ou repetidos. Este capítulo mostra as formas idiomáticas de contar palavras em Java, os casos extremos que geram problemas e qual abordagem utilizar. Ele se baseia nos fundamentos de Java Strings e String split and join.
Dividir por whitespace (o padrão confiável)
A receita padrão é fazer trim da string e depois dividi-la em um ou mais caracteres de whitespace com o 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); // 4Dois detalhes tornam isso correto. O trim() remove os espaços iniciais e finais, pois split("\\s+") em uma string que começa com whitespace produz um elemento vazio inicial. A verificação com isEmpty() trata a entrada em branco: dividir "" retorna um array de comprimento 1, não 0, então sem essa verificação uma string em branco reportaria incorretamente uma palavra.
O \\s é um literal de string Java para o regex \s, que corresponde a espaços, tabulações e quebras de linha. O + significa "um ou mais", então qualquer sequência de whitespace conta como um único separador.
Evite o split ingênuo em espaço único
É tentador escrever text.split(" ").length, mas isso divide em exatamente um espaço e falha com entradas do mundo real:
String text = " The quick brown fox ";
System.out.println(text.split(" ").length); // 8, not 4Os dois espaços iniciais produzem dois elementos vazios iniciais, e cada sequência de três espaços internos adiciona mais — então o array é ["", "", "The", "quick", "", "", "brown", "fox"], oito elementos em vez de quatro. (O split do Java descarta strings vazias finais, por isso os dois espaços no final não acrescentam nada.) Cada espaço duplicado e cada espaço inicial inflam a contagem. Dividir por " " só é seguro quando você já sabe que a entrada é uma linha delimitada por um único espaço sem espaçamento extra — o que raramente é garantido.
Contar tokens com um regex matcher
Em vez de dividir, você pode corresponder tokens de palavras diretamente e contar as correspondências. Isso evita completamente o problema dos elementos vazios:
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+ corresponde a sequências de caracteres de palavra (letras, dígitos, underscore). Como ele procura palavras em vez de procurar separadores, whitespace inicial, final e repetido é irrelevante — nenhuma verificação é necessária. A desvantagem é que \w exclui pontuação, então "well-known" com hífen conta como dois tokens. Escolha o padrão de acordo com sua definição de "palavra."
Se você precisar tokenizar um documento maior ou um stream em vez de uma única linha, o capítulo Java StringTokenizer aborda uma classe criada especificamente para dividir texto em tokens.
| Abordagem | Trata espaços extras/extremos | Seguro com string vazia | Observação |
|---|---|---|---|
split(" ") | Não | Não | Falha com espaços repetidos |
trim().split("\\s+") | Sim | Com verificação isEmpty() | O padrão recomendado |
Matcher Pattern \w+ | Sim | Sim (conta 0) | Divide na pontuação |
Um exemplo completo
O que observar na execução:
Naive split length: 8prova quesplit(" ")superconta porque cada espaço inicial e cada espaço dentro de uma sequência produz um elemento de array vazio extra.Whitespace split: 4mostra quetrim().split("\\s+")colapsa cada sequência de whitespace e dá a contagem correta.Regex matcher: 4confirma que o matcher\w+chega à mesma resposta sem nenhum trim ou verificações.Blank input words: 0demonstra por que a verificaçãoisEmpty()importa — sem ela, uma entrada em branco reportaria incorretamente uma palavra.- Todos os três métodos corretos concordam em
4, então a diferença entre eles é robustez e definição de "palavra", não o resultado com entradas limpas.