Come contare le parole in una stringa in Java
Conta le parole in una stringa Java usando trim e split su spazi bianchi, un regex matcher, ed evitando la divisione naive su singolo spazio.
Contare le parole in una stringa sembra banale — dividi sugli spazi e conta i pezzi — ma la versione naive si rompe non appena l'input ha spazi iniziali, finali o ripetuti. Questo capitolo mostra i modi idiomatici per contare le parole in Java, i casi limite che creano problemi e quale approccio scegliere. Si basa sulle nozioni di base in Java Strings e String split and join.
Dividi sugli spazi bianchi (il metodo affidabile predefinito)
La ricetta standard è fare il trim della stringa, poi dividerla su uno o più caratteri di spazio bianco 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); // 4Due dettagli rendono questo approccio corretto. Il trim() rimuove gli spazi iniziali e finali, perché split("\\s+") su una stringa che inizia con spazi bianchi produce un elemento iniziale vuoto. La guardia isEmpty() gestisce l'input vuoto: dividere "" restituisce un array di lunghezza 1, non 0, quindi senza il controllo una stringa vuota riporterebbe erroneamente una parola.
Il \\s è un letterale stringa Java per la regex \s, che corrisponde a spazi, tabulazioni e ritorni a capo. Il + significa "uno o più", quindi qualsiasi sequenza di spazi bianchi conta come un singolo separatore.
Evita la divisione naive su singolo spazio
È allettante scrivere text.split(" ").length, ma questo divide su esattamente uno spazio e si rompe con input reali:
String text = " The quick brown fox ";
System.out.println(text.split(" ").length); // 8, not 4I due spazi iniziali producono due elementi iniziali vuoti, e ogni sequenza di tre spazi interni ne aggiunge altri — quindi l'array è ["", "", "The", "quick", "", "", "brown", "fox"], otto elementi invece di quattro. (Il metodo split di Java scarta le stringhe vuote finali, ed è per questo che i due spazi finali non aggiungono nulla.) Ogni spazio doppio e ogni spazio iniziale gonfia il conteggio. Dividere su " " è sicuro solo quando si è certi che l'input è una riga delimitata da un singolo spazio senza spaziatura extra — il che è raramente garantito.
Conta i token con un regex matcher
Invece di dividere, puoi fare la corrispondenza diretta dei token di parole e contare le corrispondenze. Questo evita completamente il problema degli elementi vuoti:
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+ corrisponde a sequenze di caratteri word (lettere, cifre, underscore). Poiché cerca le parole anziché i separatori, gli spazi iniziali, finali e ripetuti sono irrilevanti — non è necessaria nessuna guardia. Il compromesso è che \w esclude la punteggiatura, quindi un termine composto come "well-known" conta come due token. Scegli il pattern che corrisponde alla tua definizione di "parola."
Se hai bisogno di tokenizzare un documento più lungo o uno stream anziché una singola riga, il capitolo Java StringTokenizer tratta una classe costruita appositamente per suddividere il testo in token.
| Approccio | Gestisce spazi extra/bordo | Sicuro con stringa vuota | Nota |
|---|---|---|---|
split(" ") | No | No | Si rompe con spazi ripetuti |
trim().split("\\s+") | Sì | Con guardia isEmpty() | Il default consigliato |
Matcher Pattern \w+ | Sì | Sì (conta 0) | Divide sulla punteggiatura |
Un esempio completo
Cosa ricavare dall'esecuzione:
Naive split length: 8dimostra chesplit(" ")conta eccessivamente perché ogni spazio iniziale e ogni spazio all'interno di una sequenza produce un ulteriore elemento array vuoto.Whitespace split: 4mostra chetrim().split("\\s+")collassa ogni sequenza di spazi bianchi e fornisce il conteggio corretto.Regex matcher: 4conferma che il matcher\w+raggiunge la stessa risposta senza alcun trim o guardie.Blank input words: 0dimostra perché la guardiaisEmpty()è importante — senza di essa, un input vuoto riporterebbe erroneamente una parola.- Tutti e tre i metodi corretti concordano su
4, quindi la differenza tra loro riguarda la robustezza e la definizione di "parola," non il risultato su input pulito.