W3docs

Comment compter les mots dans une chaîne en Java

Comptez les mots d'une chaîne Java avec trim et split sur les espaces, un matcher regex, en évitant le split naïf sur un seul espace.

Compter les mots d'une chaîne semble trivial — diviser sur les espaces et compter les parties — mais la version naïve échoue dès que l'entrée contient des espaces en début, en fin ou répétés. Ce chapitre présente les manières idiomatiques de compter les mots en Java, les cas limites qui piègent les développeurs, et quelle approche privilégier. Il s'appuie sur les bases abordées dans Java Strings et String split and join.

Diviser sur les espaces blancs (la valeur par défaut fiable)

La recette standard consiste à supprimer les espaces en début et fin de chaîne, puis à la diviser sur un ou plusieurs caractères d'espacement avec l'expression régulière \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

Deux détails rendent cela correct. Le trim() supprime les espaces de début et de fin, car split("\\s+") appliqué à une chaîne qui commence par des espaces produit un élément vide en tête. La garde isEmpty() gère les entrées vides : diviser "" renvoie un tableau de longueur 1, et non 0, donc sans cette vérification une chaîne vide signalerait à tort un mot.

\\s est un littéral de chaîne Java pour l'expression régulière \s, qui correspond aux espaces, tabulations et sauts de ligne. Le + signifie « un ou plusieurs », de sorte que toute séquence d'espaces est comptée comme un seul séparateur.

Éviter le split naïf sur un seul espace

Il est tentant d'écrire text.split(" ").length, mais cela divise sur exactement un espace et échoue sur des entrées réelles :

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

Les deux espaces en début produisent deux éléments vides en tête, et chaque séquence de trois espaces internes en ajoute davantage — le tableau est donc ["", "", "The", "quick", "", "", "brown", "fox"], huit éléments au lieu de quatre. (Le split de Java supprime les chaînes vides de fin, c'est pourquoi les deux espaces finaux n'ajoutent rien.) Chaque espace doublé et chaque espace en début gonfle le comptage. Diviser sur " " n'est sûr que si l'on sait déjà que l'entrée est une ligne délimitée par un seul espace sans espacement supplémentaire — ce qui est rarement garanti.

Compter les tokens avec un matcher regex

Au lieu de diviser, on peut rechercher directement les tokens de mots et compter les correspondances. Cela contourne entièrement le problème des éléments vides :

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+ correspond à des séquences de caractères de mot (lettres, chiffres, underscore). Parce qu'il recherche des mots plutôt que des séparateurs, les espaces en début, en fin et répétés sont sans importance — aucune garde n'est nécessaire. La contrepartie est que \w exclut la ponctuation, donc un "well-known" avec trait d'union compte comme deux tokens. Choisissez le motif en fonction de votre définition d'un « mot ».

Si vous devez tokeniser un document plus long ou un flux plutôt qu'une seule ligne, le chapitre Java StringTokenizer couvre une classe spécialement conçue pour découper du texte en tokens.

ApprocheGère les espaces supplémentaires/limitesSûre avec chaîne videRemarque
split(" ")NonNonÉchoue sur les espaces répétés
trim().split("\\s+")OuiAvec la garde isEmpty()La valeur par défaut recommandée
Matcher Pattern \w+OuiOui (compte 0)Divise sur la ponctuation

Un exemple complet

java— editable, runs on the server

Ce que l'on retient de l'exécution :

  • Naive split length: 8 prouve que split(" ") surestime le compte car chaque espace de début et chaque espace à l'intérieur d'une séquence produit un élément tableau vide supplémentaire.
  • Whitespace split: 4 montre que trim().split("\\s+") regroupe toute séquence d'espaces et donne le bon compte.
  • Regex matcher: 4 confirme que le matcher \w+ aboutit au même résultat sans aucun découpage préalable ni garde.
  • Blank input words: 0 démontre pourquoi la garde isEmpty() est importante — sans elle, une entrée vide signalerait à tort un mot.
  • Les trois méthodes correctes s'accordent sur 4, donc la différence entre elles tient à la robustesse et à la définition d'un « mot », pas au résultat sur une entrée propre.

Pratique

Pratique
Pourquoi diviser sur un seul espace surestime-t-il le nombre de mots quand la chaîne contient des espaces répétés ou en début ?
Pourquoi diviser sur un seul espace surestime-t-il le nombre de mots quand la chaîne contient des espaces répétés ou en début ?
Was this page helpful?