W3docs

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); // 4

Due 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 4

I 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.

ApproccioGestisce spazi extra/bordoSicuro con stringa vuotaNota
split(" ")NoNoSi rompe con spazi ripetuti
trim().split("\\s+")Con guardia isEmpty()Il default consigliato
Matcher Pattern \w+Sì (conta 0)Divide sulla punteggiatura

Un esempio completo

java— editable, runs on the server

Cosa ricavare dall'esecuzione:

  • Naive split length: 8 dimostra che split(" ") conta eccessivamente perché ogni spazio iniziale e ogni spazio all'interno di una sequenza produce un ulteriore elemento array vuoto.
  • Whitespace split: 4 mostra che trim().split("\\s+") collassa ogni sequenza di spazi bianchi e fornisce il conteggio corretto.
  • Regex matcher: 4 conferma che il matcher \w+ raggiunge la stessa risposta senza alcun trim o guardie.
  • Blank input words: 0 dimostra perché la guardia isEmpty() è 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.

Pratica

Pratica
Perché dividere su un singolo spazio conta troppe parole quando la stringa ha spazi ripetuti o iniziali?
Perché dividere su un singolo spazio conta troppe parole quando la stringa ha spazi ripetuti o iniziali?
Was this page helpful?