Optælling af ord i en streng med Java

1. Oversigt

I denne vejledning skal vi gå over forskellige måder at tælle ord i en given streng ved hjælp af Java.

2. Brug StringTokenizer

En enkel måde at tælle ord på i en streng i Java er at bruge StringTokenizer klasse:

assertEquals (3, ny StringTokenizer ("tre blinde mus"). countTokens ()); assertEquals (4, new StringTokenizer ("see \ thow \ tthey \ trun"). countTokens ());

Noter det StringTokenizer tager automatisk pleje af hvidt rum for os, som faner og vognretur.

Men det kan gå dårligt nogle steder, som bindestreger:

assertEquals (7, ny StringTokenizer ("landmandens kone - hun var fra Albuquerque"). countTokens ());

I dette tilfælde ønsker vi, at "kone" og "hun" skal være forskellige ord, men da der ikke er noget mellemrum mellem dem, mislykkes standardindstillingerne os.

Heldigvis, StringTokenizer sendes med en anden konstruktør. Vi kan passere en afgrænser ind i konstruktøren for at få ovenstående til at virke:

assertEquals (7, ny StringTokenizer ("landmandens kone - hun var fra Albuquerque", "-"). countTokens ());

Dette er nyttigt, når du prøver at tælle ordene i en streng fra noget som en CSV-fil:

assertEquals (10, ny StringTokenizer ("gjorde du, nogensinde, se sådan, et, syn, i, dit, liv", ","). countTokens ());

Så, StringTokenizer er enkelt, og det får os det meste af vejen derhen.

Lad os dog se, hvilke ekstra hestekræfter regulære udtryk kan give os.

3. Regulære udtryk

For at vi kan komme med et meningsfuldt regulært udtryk for denne opgave, er vi nødt til at definere, hvad vi betragter som et ord: et ord starter med et bogstav og slutter enten med et mellemrumstegn eller et tegnsætningstegn.

Med dette i tankerne, givet en streng, er det, vi vil gøre, at opdele den streng på hvert punkt, vi støder på mellemrum og tegnsætningstegn, og derefter tælle de resulterende ord.

assertEquals (7, countWordsUsingRegex ("landmandens kone - hun var fra Albuquerque"));

Lad os skrue tingene lidt op for at se styrken ved regex:

assertEquals (9, countWordsUsingRegex ("ingen & # skal% nogensinde skrive-lignende, dette; men: godt"));

Det er ikke praktisk at løse denne ved blot at sende en afgrænser til StringTokenizer da vi skulle definere en rigtig lang afgrænser for at prøve at liste alle mulige tegnsætningstegn.

Det viser sig, at vi virkelig ikke behøver at gøre meget, passerer regex[\ pP \ s && [^ ']] +tildelemetode tilSnorklasse vil gøre tricket:

offentlig statisk int countWordsUsingRegex (String arg) {if (arg == null) {return 0; } sidste streng [] ord = arg.split ("[\ pP \ s && [^ ']] +"); returnere ord. længde; }

Regex [\ pP \ s && [^ ']] + finder en hvilken som helst længde af enten tegnsætningstegn eller mellemrum og ignorerer apostroftegnsætningstegnet.

For at finde ud af mere om regulære udtryk, se Regular Expressions on Baeldung.

4. Sløjfer og Snor API

Den anden metode er at have et flag, der holder styr på de ord, der er stødt på.

Vi sætter flaget til ORD når du støder på et nyt ord og øger antallet af ord, derefter tilbage til SEPARATOR når vi støder på et ikke-ord (tegnsætning eller mellemrumstegn).

Denne tilgang giver os de samme resultater, som vi fik med regelmæssige udtryk:

assertEquals (9, countWordsManually ("ingen & # skal% nogensinde skrive-lignende, dette men godt")); 

Vi er nødt til at være forsigtige med specielle tilfælde, hvor tegnsætningstegn ikke er ordskillere, for eksempel:

assertEquals (6, countWordsManually ("landmandens kone - hun var fra Albuquerque"));

Det, vi ønsker her, er at tælle ”landmandens” som et ord, skønt apostrofen ”“ ”er et tegnsætningstegn.

I regex-versionen havde vi fleksibiliteten til at definere, hvad der ikke kvalificerer som et tegn ved hjælp af regex. Men nu hvor vi skriver vores egen implementering, vi er nødt til at definere denne udelukkelse i en separat metode:

privat statisk boolsk isAllowedInWord (char charAt) 

Så hvad vi har gjort her er at tillade med et ord alle tegn og juridiske tegnsætningstegn, apostrofen i dette tilfælde.

Vi kan nu bruge denne metode i vores implementering:

offentlig statisk int countWordsManually (String arg) {if (arg == null) {return 0; } int flag = SEPARATOR; int-antal = 0; int stringLength = arg.length (); int characterCounter = 0; mens (characterCounter <stringLength) {if (isAllowedInWord (arg.charAt (characterCounter)) && flag == SEPARATOR) {flag = WORD; tælle ++; } ellers hvis (! isAllowedInWord (arg.charAt (characterCounter))) {flag = SEPARATOR; } tegnTæller ++; } returantal }

Den første betingelse markerer et ord, når det møder et og forøger tælleren. Den anden betingelse kontrollerer, om tegnet ikke er et bogstav, og sætter flaget til SEPARATOR.

5. Konklusion

I denne vejledning har vi set på måder at tælle ord ved hjælp af flere tilgange. Vi kan vælge ethvert, afhængigt af vores særlige brugssag.

Som normalt kan kildekoden til denne tutorial findes på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found