Lielākā daļa Java programmētāju ir izmantojuši java.util.StringTokenizer
klasi kādā vai citā laikā. Tā ir ērta klase, kas būtībā marķē (pārtrauc) ievades virkni, pamatojoties uz atdalītāju, un pēc pieprasījuma piegādā marķierus. (Tokenizācija ir rakstzīmju secības pārveidošana par žetoniem, kurus saprot jūsu programma.)
Lai arī ērts, StringTokenizer
funkcionalitāte ir ierobežota. Klase vienkārši meklē atdalītāju ievades virknē un pārtrauc virkni, tiklīdz atdalītājs ir atrasts. Tas nepārbauda apstākļus, piemēram, vai atdalītājs atrodas apakškārtā, kā arī neatgriež marķieri kā ""
(virknes garums 0), kad ievadā tiek atrasti divi secīgi atdalītāji. Lai izpildītu šos ierobežojumus, Java 2 platformai (JDK 1.2 un jaunākām versijām) ir pievienots BreakIterator
klase, kas ir uzlabots marķieris StringTokenizer
. Tā kā šāda klase nav JDK 1.1.x versijā, izstrādātāji bieži pavada daudz laika, rakstot oriģinālu marķieri, kas atbilst viņu prasībām. Lielā projektā, kas saistīts ar datu formātu apstrādi, nav reti sastopams daudz tādu pielāgotu klašu, kas peld apkārt.
Šī padoma mērķis ir palīdzēt jums uzrakstīt sarežģītu marķieri, izmantojot esošo StringTokenizer
.
StringTokenizer ierobežojumi
Jūs varat izveidot StringTokenizer
izmantojot jebkuru no šiem trim konstruktoriem:
StringTokenizer (virknes sInput)
: Pārtraukumi uz atstarpes ("", "\ t", "\ n"
).StringTokenizer (virknes sInput, virknes sDelimiter)
: PārtraukumisDelimiter
.StringTokenizer (String sInput, String sDelimiter, Būla bReturnTokens)
: PārtraukumisDelimiter
, bet jabReturnTokens
ir iestatīts uz true, tad atdalītājs tiek atgriezts arī kā marķieris.
Pirmais konstruktors nepārbauda, vai ievades virkne satur apakšvirknes. Kad virkne "sveiki. Šodien es" dodos uz savu dzimto pilsētu "
ir marķēts uz atstarpes, rezultāts ir marķieros Sveiki.
, Šodien
, "Es
, esmu
, "
, iet
, tā vietā Sveiki.
, Šodien
, "ES esmu "
, iet
.
Otrais konstruktors nepārbauda atdalītāju secīgu izskatu. Kad virkne "grāmata, autors, publikācija ,,, publicēšanas datums"
ir marķēts ","
, StringTokenizer
atgriež četrus marķierus ar vērtībām grāmata
, autors
, publikācija
, un publicēšanas datums
sešu vērtību vietā grāmata
, autors
, publikācija
, ""
, ""
, un publicēšanas datums
, kur ""
nozīmē virkni ar garumu 0. Lai iegūtu sešus, jums jāiestata StringTokenizer
's bReturnTokens
parametrs uz true.
Parametra iestatīšanas uz patieso iezīme ir svarīga, jo tā dod priekšstatu par secīgu atdalītāju klātbūtni. Piemēram, ja dati tiek iegūti dinamiski un tiek izmantoti, lai atjauninātu tabulu datu bāzē, kur ievades marķieri kartē kolonnu vērtības, tad marķierus nevaram kartēt ar datu bāzes kolonnām, jo neesam pārliecināti, kuras kolonnas būtu jāiestata uz ""
. Piemēram, mēs vēlamies pievienot ierakstus tabulai ar sešām kolonnām, un ievaddatos ir divi secīgi atdalītāji. Rezultāts no StringTokenizer
šajā gadījumā ir pieci marķieri (jo divi secīgi atdalītāji apzīmē marķieri ""
, kas StringTokenizer
novārtā), un mums ir jāiestata seši lauki. Mēs arī nezinām, kur parādās secīgais atdalītājs, tādējādi uz kuru kolonnu ir jāiestata ""
.
Trešais konstruktors nedarbosies, ja pats marķieris ir vienāds (pēc garuma un vērtības) ar atdalītāju un atrodas apakšstruktūrā. Kad virkne "grāmata, autors, publikācija, \", \ ", publicēšanas datums"
ir marķēts (šī virkne satur ,
kā marķieri, kas ir tāds pats kā tā atdalītājs) uz virknes ,
, rezultāts ir grāmata
, autors
, publikācija
, "
, "
, publicēšanas datums
(ar sešiem žetoniem), nevis grāmata
, autors
, publikācija
, ,
(komata raksturs), publicēšanas datums
(ar pieciem žetoniem). Paturiet prātā, pat iestatot bReturnTokens
(trešais parametrs StringTokenizer
) uz true šajā gadījumā jums nepalīdzēs.
Tokenizatora pamatvajadzības
Pirms rīkoties ar kodu, jums jāzina laba tokenizatora pamatvajadzības. Tā kā Java izstrādātāji ir pieraduši pie StringTokenizer
klasē, labam marķierim vajadzētu būt visām noderīgajām metodēm, kuras nodrošina klase, piemēram, hasMoreTokens ()
, nextToken ()
, countTokens ()
.
Šī padoma kods ir vienkāršs un lielākoties pats par sevi saprotams. Būtībā esmu izmantojis StringTokenizer
klase (izveidota ar bReturnTokens
iestatīts kā patiess) iekšēji un nodrošināja iepriekš minētās metodes. Tā kā dažos gadījumos atdalītājs ir nepieciešams kā marķieri (ļoti retos gadījumos), bet dažos gadījumos tas nav, marķierim pēc pieprasījuma jānorāda atdalītājs kā marķieris. Kad izveidojat a PowerfulTokenizer
objektu, nododot tikai ievades virkni un atdalītāju, tas iekšēji izmanto a StringTokenizer
ar bReturnTokens
iestatīts uz patiesu. (Iemesls tam ir, ja a StringTokenizer
ir izveidots bez bReturnTokens
iestatīta uz patiesu, tad tas ir ierobežots, lai pārvarētu iepriekš norādītās problēmas). Lai pareizi rīkotos ar marķieri, kods pārbauda, vai bReturnTokens
ir iestatīts uz true dažās vietās (aprēķinot kopējo žetonu skaitu un nextToken ()
).
Kā jūs, iespējams, novērojāt, PowerfulTokenizer
īsteno Uzskaitīšana
interfeisu, tādējādi ieviešot hasMoreElements ()
un nextElement ()
metodes, kas vienkārši deleģē zvanu hasMoreTokens ()
un nextToken ()
, attiecīgi. (Īstenojot Uzskaitīšana
saskarne, PowerfulTokenizer
kļūst savietojams ar StringTokenizer
.) Apsvērsim piemēru. Sakiet, ka ievades virkne ir "sveiki, šodien ,,, \" Es, esmu \ ", dodos uz ,,, \" pirkt, grāmatu, \ ""
un norobežotājs ir ,
. Šī virkne, kad tokenizēta, atgriež vērtības, kā parādīts 1. tabulā:
Tips | Žetonu skaits | Žetoni |
---|---|---|
| 19 | sveiki:,: Šodien:,:,:,: "Es:,: esmu":,: dodos uz:,:,:,: "nopirkt:,: a:,: grāmata " (šeit raksturs : atdala žetonus) |
| 13 | sveiki:,: Šodien:,: "": "": Es, esmu:,: dodos:,: "": "": nopirkt grāmatu (kur "" nozīmē virkni ar garumu 0) |
| 9 | labdien: Šodien: "": "": Es esmu gatavojas: "": "": nopirkt grāmatu |
Ievades virkne satur 11 komatus (,
) rakstzīmes, no kurām trīs ir apakšvirkņu iekšpusē un četras parādās secīgi (kā Šodien ,,,
veic divus secīgus komatu parādīšanās gadījumus, no kuriem pirmais ir komats Šodien
atdalītājs). Šeit ir loģika, aprēķinot žetonu skaitu PowerfulTokenizer
gadījums:
- Gadījumā, ja
bReturnTokens = taisnība
, reiziniet norobežotāju skaitu apakškārtās iekšā ar 2 un atņemiet šo summu no faktiskās kopsummas, lai iegūtu marķieru skaitu. Iemesls ir apakšvirknei"pirkt, grāmatu"
,StringTokenizer
atgriezīs piecus žetonus (t.i.,pirkt:,: a:,: grāmata
), kamērPowerfulTokenizer
atgriezīs vienu marķieri (t.i.,pirkt, grāmatu
). Atšķirība ir četras (t.i., 2 * atdalītāju skaits apakšvirknes iekšpusē). Šī formula labi der jebkuram apakškārtam, kas satur atdalītājus. Jāapzinās īpašais gadījums, kad marķieris pats ir vienāds ar norobežotāju; tam nevajadzētu samazināt skaitīšanas vērtību. - Līdzīgi arī attiecībā uz
bReturnTokens = nepatiesa
, atņemiet izteiksmes vērtību [kopējie atdalītāji (11) - secīgie atdalītāji (4) + atdalītāju skaits apakškārtās (3)] no faktiskā kopsummas (19), lai iegūtu marķieru skaitu. Tā kā šajā gadījumā mēs neatgriežam atdalītājus, tie (neparādoties secīgi vai apakšvirkņu iekšpusē) mums nav noderīgi, un iepriekš minētā formula dod mums kopējo marķieru skaitu (9).
Atcerieties šīs divas formulas, kas ir PowerfulTokenizer
. Šīs formulas darbojas gandrīz visos attiecīgajos gadījumos. Tomēr, ja jums ir sarežģītākas prasības, kas nav piemērotas šīm formulām, pirms sākat kodēt, jums jāapsver dažādi piemēri, lai izstrādātu savu formulu.
// pārbaudiet, vai atdalītājs atrodas apakškārtā (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 ()
metode iegūst žetonus, izmantojot StringTokenizer.nextToken
, un pārbauda marķiera dubultās pēdiņas rakstzīmi. Ja metode atrod šīs rakstzīmes, tā iegūst vairāk marķieru, līdz neatrod nevienu ar dubultu pēdiņu. Tas arī glabā marķieri mainīgajā (sPrevToken
; skatīt avota kodu), lai pārbaudītu secīgu atdalītāju parādīšanos. Ja nextToken ()
atrod secīgus marķierus, kas ir vienādi ar norobežotāju, tad tas atgriežas ""
(virkne ar garumu 0) kā marķieri.
Līdzīgi hasMoreTokens ()
metode pārbauda, vai jau pieprasīto marķieru skaits ir mazāks par kopējo žetonu skaitu.
Ietaupiet izstrādes laiku
Šis raksts ir iemācījis, kā viegli uzrakstīt spēcīgu marķieri. Izmantojot šos jēdzienus, jūs varat ātri uzrakstīt sarežģītus marķierus, tādējādi ietaupot ievērojamu izstrādes laiku.
Bhabani Padhi ir Java arhitekts un programmētājs, kurš pašlaik strādā pie Web un uzņēmuma lietojumprogrammu izstrādes, izmantojot Java tehnoloģiju, UniteSys, Austrālijā. Iepriekš viņš strādāja Baltimore Technologies, Austrālijā pie e-drošības produktu izstrādes, un Fujitsu, Austrālijā pie EJB serveru izstrādes projekta. Bhabani interešu lokā ir sadalītās skaitļošanas, mobilo un tīmekļa lietojumprogrammu izstrāde, izmantojot Java tehnoloģiju.Uzziniet vairāk par šo tēmu
- Iegūstiet šī padoma avota kodu
//images.techhive.com/downloads/idge/imported/article/jvw/2001/06/powerfultokenizer.java
- Lai iegūtu vairāk informācijas par BreakIterator
//java.sun.com/products/jdk/1.2/docs/api/java/text/BreakIterator.html
- Skatīt visu iepriekšējo Java padomi un iesniedziet savu
//www.javaworld.com/javatips/jw-javatips.index.html
- Vairāk Ievads rakstus, apmeklējiet JavaWorld 's Aktuālais rādītājs
//www.javaworld.com/javaworld/topicalindex/jw-ti-introlevel.html
- Uzziniet Java no paša sākuma JavaWorld 's Java 101 kolonna
//www.javaworld.com/javaworld/topicalindex/jw-ti-java101.html
- Java eksperti atbild uz jūsu visgrūtākajiem Java jautājumiem JavaWorld 's Java jautājumi un atbildes kolonna
//www.javaworld.com/javaworld/javaqa/javaqa-index.html
- Pierakstieties JavaWorld šonedēļ bezmaksas iknedēļas e-pasta biļetens, lai uzzinātu, kas jauns JavaWorld
//www.idg.net/jw-subscribe
Šo stāstu “Java Tip 112: Uzlabojiet informācijas bagātīgu virkņu marķēšanu” sākotnēji publicēja JavaWorld.