Večina programerjev Java uporablja java.util.StringTokenizer
razredu ob določenem času. V bistvu je priročen razred tokenizira (razbije) vhodni niz na podlagi ločila in na zahtevo dobavi žetone. (Tokenizacija je pretvorba zaporedij znakov v žetone, ki jih razume vaš program.)
Čeprav priročen, StringTokenizer
funkcionalnost uporabnika je omejena. Razred preprosto poišče ločilo v vhodnem nizu in prelomi niz, ko ga najdete. Ne preveri pogojev, na primer, ali je ločilo znotraj podniza, niti ne vrne žetona kot ""
(dolžina niza 0), ko v vhodu najdemo dva zaporedna ločila. Za izpolnitev teh omejitev je platforma Java 2 (JDK 1.2 naprej) priložena BreakIterator
razred, ki je izboljšan tokenizer nad StringTokenizer
. Ker tak razred ni prisoten v JDK 1.1.x, razvijalci pogosto porabijo veliko časa za pisanje originalnega tokenizatorja, ki ustreza njihovim zahtevam. V velikem projektu, ki vključuje obdelavo podatkovnih formatov, ni redko najti veliko takih prilagojenih razredov, ki plavajo.
Namig tega nasveta vas bo vodil skozi pisanje prefinjenega tokenizatorja z uporabo obstoječega StringTokenizer
.
Omejitve StringTokenizerja
Lahko ustvarite StringTokenizer
z uporabo katerega koli od naslednjih treh konstruktorjev:
StringTokenizer (String sInput)
: Odmori na praznem prostoru ("", "\ t", "\ n"
).StringTokenizer (String sInput, String sDelimiter)
: OdmorisOmejitelj
.StringTokenizer (String sInput, String sDelimiter, boolean bReturnTokens)
: OdmorisOmejitelj
, ampak čebReturnTokens
je nastavljeno na true, potem je tudi ločilo vrnjeno kot žeton.
Prvi konstruktor ne preveri, ali vhodni niz vsebuje podnize. Ko niz "zdravo. Danes \" grem \ "v domače mesto"
je označeno na praznem prostoru, rezultat je v žetonih zdravo.
, Danes
, "JAZ
, sem
, "
, gremo
, namesto zdravo.
, Danes
, "Jaz sem "
, gremo
.
Drugi konstruktor ne preveri zaporednega videza ločil. Ko niz "knjiga, avtor, publikacija ,,, datum objave"
je tokenizirano ","
, StringTokenizer
vrne štiri žetone z vrednostmi knjigo
, avtor
, objave
, in datum objave
namesto šestih vrednosti knjigo
, avtor
, objave
, ""
, ""
, in datum objave
, kje ""
pomeni niz dolžine 0. Če želite dobiti šest, morate nastaviti StringTokenizer
je bReturnTokens
parameter na true.
Značilnost nastavitve parametra na true je pomembna, saj daje predstavo o prisotnosti zaporednih ločil. Če na primer podatke dobimo dinamično in jih uporabimo za posodobitev tabele v zbirki podatkov, kjer se vhodni žetoni preslikajo na vrednosti stolpcev, žetonov ne moremo preslikati s stolpci baze podatkov, saj nismo prepričani, katere stolpce je treba nastaviti do ""
. Na primer, v tabelo s šestimi stolpci želimo dodati zapise, vhodni podatki pa vsebujejo dva zaporedna ločila. Rezultat iz StringTokenizer
v tem primeru je pet žetonov (saj dva zaporedna ločila predstavljata žeton ""
, ki StringTokenizer
zanemarja) in nastaviti moramo šest polj. Prav tako ne vemo, kje se pojavi zaporedna ločila, zato naj bo nastavljen na kateri stolpec ""
.
Tretji konstruktor ne bo deloval, če je žeton sam (po dolžini in vrednosti) ločevalniku in je v podnizu. Ko niz "knjiga, avtor, publikacija, \", \ ", datum objave"
je tokenizirano (ta niz vsebuje ,
kot žeton, kar je enako kot ločilo) na nizu ,
, rezultat je knjigo
, avtor
, objave
, "
, "
, datum objave
(s šestimi žetoni) namesto knjigo
, avtor
, objave
, ,
(znak vejice), datum objave
(s petimi žetoni). Pazite, celo nastavite bReturnTokens
(tretji parameter do StringTokenizer
) to true vam v tem primeru ne bo pomagalo.
Osnovne potrebe tokenizatorja
Preden se lotite kode, morate poznati osnovne potrebe dobrega tokenizatorja. Ker so razvijalci Java navajeni na StringTokenizer
razreda, bi moral imeti dober tokenizer vse uporabne metode, ki jih ponuja razred, kot je npr hasMoreTokens ()
, nextToken ()
, countTokens ()
.
Koda tega nasveta je preprosta in večinoma samoumevna. V bistvu sem uporabil StringTokenizer
razred (ustvarjen z bReturnTokens
interno nastavljen na true) in zagotavlja zgoraj omenjene metode. Ker je v nekaterih primerih ločilo potrebno kot žetoni (v zelo redkih primerih), v nekaterih pa ne, mora tokenizer na zahtevo dodati ločilo kot žeton. Ko ustvarite datoteko Zmogljiv tokenizer
objekt, ki posreduje samo vhodni niz in ločilo, interno uporablja a StringTokenizer
s bReturnTokens
nastavljeno na true. (Razlog za to je, če a StringTokenizer
je ustvarjena brez bReturnTokens
nastavljeno na true, potem je omejeno pri premagovanju prej navedenih težav). Za pravilno ravnanje s tokenizatorjem koda preveri, ali bReturnTokens
je na nekaj mestih nastavljeno na true (izračun skupnega števila žetonov in nextToken ()
).
Kot ste morda opazili, Zmogljiv tokenizer
izvaja Naštevanje
vmesnik, s čimer se izvaja hasMoreElements ()
in nextElement ()
metode, ki preprosto prenesejo klic na hasMoreTokens ()
in nextToken ()
oziroma. (Z izvajanjem Naštevanje
vmesnik, Zmogljiv tokenizer
postane združljiv z StringTokenizer
.) Oglejmo si primer. Recimo, da je vhodni niz "zdravo, danes ,,, \" jaz sem \ ", grem ,,, \" kupi, a, knjigo \ ""
in ločilo je ,
. Ta niz, ko je tokeniziran, vrne vrednosti, kot je prikazano v tabeli 1:
Tip | Število žetonov | Žetoni |
---|---|---|
| 19 | zdravo:,: Danes:,:,::,: "I:,: am":,: bo:,::,:,: "kupi:,: a:,: knjiga " (tukaj lik : ločuje žetone) |
| 13 | živjo:,: Danes:,: "": "": Jaz sem:,: bom:,: "": "": kupi knjigo (kje "" pomeni niz dolžine 0) |
| 9 | zdravo: Danes: "": "": Jaz bom: grem: "": "": kupi knjigo |
Vhodni niz vsebuje 11 vejic (,
), od katerih so trije znotraj podnizov, štirje pa zaporedno (kot Danes ,,,
naredi dva zaporedna nastopa z vejico, pri čemer je prva vejica Danes
ločilo). Tu je logika pri izračunu števila žetonov v Zmogljiv tokenizer
Ovitek:
- V primeru
bReturnTokens = true
, pomnožite število ločil znotraj podnizov z 2 in odštejte to količino od dejanske vsote, da dobite število žetonov. Razlog je podniz"kupi, rezerviraj"
,StringTokenizer
vrne pet žetonov (tj.kupiti:,: a:,: knjiga
), medtemZmogljiv tokenizer
bo vrnil en žeton (tj.kupiti, knjigo
). Razlika je štiri (tj. 2 * število ločil znotraj podniza). Ta formula dobro velja za kateri koli podniz, ki vsebuje ločila. Zavedajte se posebnega primera, ko je žeton enak ločevalniku; to ne sme zmanjšati vrednosti štetja. - Podobno za primer
bReturnTokens = false
, odštejte vrednost izraza [skupno ločilo (11) - zaporedna ločila (4) + število ločil znotraj podnizov (3)] od dejanskega števila (19), da dobite število žetonov. Ker v tem primeru ločil ne vrnemo, nam (ne da bi se pojavili zaporedoma ali znotraj podnizov) ne koristijo, zgornja formula pa nam daje skupno število žetonov (9).
Zapomni si ti dve formuli, ki sta srcu Zmogljiv tokenizer
. Te formule delujejo v skoraj vseh primerih. Če pa imate bolj zapletene zahteve, ki niso primerne za te formule, morate pred hitenjem kodiranja razmisliti o različnih primerih, da razvijete svojo formulo.
// preverimo, ali je ločilo znotraj podniza for (int i = 1; iThe
countTokens()
method checks whether the input string contains double quotes. If it does, then it decrements the count and updates the index to the index of the next double quote in that string (as shown in the above code segment). IfbReturnTokens
is false, then it decrements the count by the total number of nonsubsequent delimiters present in the input string.// return " "="" as="" token="" if="" consecutive="" delimiters="" are="" found.="" if="" (="" (sprevtoken.equals(sdelim))="" &&="" (stoken.equals(sdelim))="" )="" {="" sprevtoken="sToken;" itokenno++;="" return="" "";="" }="" check="" whether="" the="" token="" itself="" is="" equal="" to="" the="" delimiter="" if="" (="" (stoken.trim().startswith("\""))="" &&="" (stoken.length()="=" 1)="" )="" {="" this="" is="" a="" special="" case="" when="" token="" itself="" is="" equal="" to="" delimiter="" string="" snexttoken="oTokenizer.nextToken();" while="" (!snexttoken.trim().endswith("\""))="" {="" stoken="" +="sNextToken;" snexttoken="oTokenizer.nextToken();" }="" stoken="" +="sNextToken;" sprevtoken="sToken;" itokenno++;="" return="" stoken.substring(1,="" stoken.length()-1);="" }="" check="" whether="" there="" is="" a="" substring="" inside="" the="" string="" else="" if="" (="" (stoken.trim().startswith("\""))="" &&="" (!((stoken.trim().endswith("\""))="" &&="" (!stoken.trim().endswith("\"\""))))="" )="" {="" if="" (otokenizer.hasmoretokens())="" {="" string="" snexttoken="oTokenizer.nextToken();" check="" for="" presence="" of="" "\"\""="" while="" (!((snexttoken.trim().endswith("\""))="" &&="" (!snexttoken.trim().endswith("\"\"")))="" )="" {="" stoken="" +="sNextToken;" if="" (!otokenizer.hasmoretokens())="" {="" snexttoken="" ;="" break;="" }="" snexttoken="oTokenizer.nextToken();" }="" stoken="" +="sNextToken;" }="" }="">
The nextToken ()
metoda dobi žetone z uporabo StringTokenizer.nextToken
in preveri, ali je v žetonu znak z dvojnimi narekovaji. Če metoda najde te znake, dobi več žetonov, dokler jih ne najde z dvojnim narekovajem. Žeton shrani tudi v spremenljivko (sPrevToken
; glej izvorno kodo) za preverjanje zaporednih pojavitev ločil. Če nextToken ()
najde zaporedne žetone, ki so enaki ločevalniku, nato pa se vrne ""
(niz z dolžino 0) kot žeton.
Podobno je hasMoreTokens ()
metoda preveri, ali je število že zahtevanih žetonov manjše od skupnega števila žetonov.
Prihranite čas za razvoj
Ta članek vas je naučil, kako enostavno napisati zmogljiv tokenizer. Z uporabo teh konceptov lahko hitro napišete kompleksne tokenizatorje in tako prihranite pomemben čas za razvoj.
Bhabani Padhi je javanski arhitekt in programer, ki trenutno dela na razvoju spletnih in podjetniških aplikacij z uporabo Java tehnologije v podjetju UniteSys v Avstraliji. Prej je delal v podjetju Baltimore Technologies v Avstraliji pri razvoju izdelkov za e-varnost in v Fujitsu v Avstraliji pri projektu razvoja strežnika EJB. Interesi Bhabanija vključujejo porazdeljeno računalništvo, mobilne in razvoj spletnih aplikacij z uporabo tehnologije Java.Preberite več o tej temi
- Pridobite izvorno kodo za ta nasvet
//images.techhive.com/downloads/idge/imported/article/jvw/2001/06/powerfultokenizer.java
- Za več informacij o BreakIteratorju
//java.sun.com/products/jdk/1.2/docs/api/java/text/BreakIterator.html
- Oglejte si vse prejšnje Java Nasveti in oddajte svojega
//www.javaworld.com/javatips/jw-javatips.index.html
- Za več Uvodna raven člankov, obiščite JavaWorld 's Aktualni indeks
//www.javaworld.com/javaworld/topicalindex/jw-ti-introlevel.html
- Naučite se Java od začetka v JavaWorld 's Java 101 stolpec
//www.javaworld.com/javaworld/topicalindex/jw-ti-java101.html
- Strokovnjaki za Javo odgovarjajo na najtežja vprašanja v zvezi z Javo JavaWorld 's Vprašanja in odgovori o Javi stolpec
//www.javaworld.com/javaworld/javaqa/javaqa-index.html
- Prijavite se za Ta teden JavaWorld brezplačno tedensko e-poštno glasilo, če želite izvedeti, kaj je novega JavaWorld
//www.idg.net/jw-subscribe
To zgodbo z naslovom "Java Nasvet 112: Izboljšanje tokenizacije nizov, bogatih z informacijami" je prvotno objavil JavaWorld.