Razbijmo vhodni niz v žetone (tokens) z uporabo razreda StringTokenizer

Uvod

Ko programiramo  na kateremkoli splošnem programskem jeziku je večkrat potrebno razbiti velik string v več manjših. Kakorkoli že, če delate z Unix sistemskimi datotekami ali s starejšimi Windows "*.ini" datotekami ali pa npr. s tekstovno bazo podatkov, večkrat berete zapise teh informacij in jih potem razbijete v manjše dele (npr. če preberete stavek in ga želite razbiti na manjše dele, npr. na besede). Zadnje čase sem uporabljal to metodo za programsko interpretiranje (branje) vsebine HTML strani za mrežne "robote" (ang. web "robots" - pomeni nekaj podobnega kot programsko ustvarjanje internet strani).

V tem članku bomo demonstrirali kako razbiti Java  String-e v manjše komponente, ki jih v Javi imenujemo  tokens (žetoni).  Torej, če kadarkoli govorimo o žetonih mislimo na manjše String-e v nekem večjem String-u. Začeli bomo z razbijanjem(razstavljanjem) preprostih dobro znanih stavkov v besede, potem pa bomo demonstrirali, kako uporabiti enako tehniko za delo s tekstovno bazo podatkov.

Razbiranje stavkov v besede

Eden najbolj znanih stavkov v Ameriški zgodovini se začne z naslednjimi besedami "Four score and seven years ago".  Za naše namene predpostavimo, da je stavek shranjen v spremenljivki z imenom  speech, na primer tako:

Enostaven del kode, kak razbiti ta stavek v samostojne besede z uporabo StringTokenizer Java razreda bi zgledal tako: V tem primeru je spremenljivka speech podana v StringTokenizer konstruktor metodo. Ker StringTokenizer nima vhodnega parametra v katerega bi podali ločilec zapisa (field separator), s katerimi bi ločili posamezne dele med sabo, zato razred uporabi privzete ločilce zapisa in predpostavlja, da so zapisi ločeni z belimi (nevidnimi) znaki (to so presledki, tabulatorji in prehodi v novo vrstico). Zatorej, vsakič ko gremo skozi while zanko se izpiše ena beseda. Podani izpis je potem:  While zanka vsakič tudi preveri, če je še kaj žetonov (z metodo hasMoreTokens() razreda StringTokenizer) v objektu st. Če jih je se potem izvrši stavek println. Kadar pa ni nič več žetonov  se while zanka preneha izvrševati.

Še eno pojasnilo preden bomo nadaljevali. Če želite preizkusiti ta primer morate priložiti java.util.* paket. To storite z naslednjo vrstico:

V tem paketu je vsebovan tudi razred StringTokenizer.

Primer uporabe tekstovne baze podatkovne datoteke

V pravkar pokazanem primeru je bil tekst string razbit v več žetonov. Seveda v anlgeškem jeziku mislimo na žetone kot na besede in te besede so ponavadi ločene z belimi (nevidnimi) znaki (tabulatorji, presledki, prehodni v novo vrstico). V naslednjem primeru bomo pokazali, kako razbiti podatkovni zapis(ang. database record, ki je ločen z dvopičji) v žetone, ki jim ponavadi pravimo polja (fields).

Naslednja dva zapisa sta iz hipotetične podatkovne datoteke imenovane customer.db, ki vsebuje podatke o strankah.  Vsak zapis vsebuje informacijo o stranki vključno z naslovom in je sestavljen iz imena, priimka, mesta in države strankinega naslova. Znotraj zapisa je vsako polje (tu so polja ime, priimek, mesto in država strankinega naslova) ločeno z znakom za dvopičje. Primera dveh zapisov sta:

Recimo, da smo prebrali prvi zapis (to je Homer Simpson zapis) v spremenljivko tipa String z imenom dbRecord. Ta zapis bi lahko razbili v štiri polja in jih izpisali na naslednji način: V tem primeru predpostavimo, da spremenljivka dbRecord že vsebuje celoten prvi zapis iz naše podatkovne baze. Ker vemo, da so zapisi ločeni z dvopičjem, bomo določili, da naj bo ločilec polj (ang. field separator, to je znak, s katerimi bomo razločevali žetone med seboj) znak za dvopičje, potem bomo poklicali StringTokenizer konstruktor tako: Ko smo napisali ta programski stavek je enostavno razbijati zapise v štiri žetone z uporabo metode nextToken() iz razreda StringTokenizer, ki prebere naslednji žeton v zapisu.

Ta tehnika je demonstrirana v celoti v Izpisu 1, kjer je celotna customer.db baza podatkov prebrana (zapis za zapisom) in izpisana.
 
 
  import java.io.*;
  import java.util.*;

  class TokenTest { 

     public static void main (String[] args) {
        TokenTest tt = new TokenTest();
        tt.dbTest();
     }
 

     void dbTest() { 

        DataInputStream dis = null;
        String dbRecord = null;

        try { 

           File f = new File("customer.db");
           FileInputStream fis = new FileInputStream(f); 
           BufferedInputStream bis = new BufferedInputStream(fis); 
           dis = new DataInputStream(bis);

           // read the first record of the database
           while ( (dbRecord = dis.readLine()) != null) {

              StringTokenizer st = new StringTokenizer(dbRecord, ":");
              String fname = st.nextToken();
              String lname = st.nextToken();
              String city  = st.nextToken();
              String state = st.nextToken();

              System.out.println("First Name:  " + fname);
              System.out.println("Last Name:   " + lname);
              System.out.println("City:        " + city);
              System.out.println("State:       " + state + "\n");
           }

        } catch (IOException e) { 
           // catch io errors from FileInputStream or readLine() 
           System.out.println("Uh oh, got an IOException error: " + e.getMessage()); 

        } finally { 
           // if the file opened okay, make sure we close it 
           if (dis != null) {
              try {
                 dis.close();
              } catch (IOException ioe) {
                 System.out.println("IOException error trying to close the file: " +
                                    e.getMessage()); 
              }

           } // end if

        } // end finally

     } // end dbTest

  } // end class
 

Čeprav prikazana koda  ni dober primer objektno orientiranega stila programiranja, ampak prikazuje našo tehniko razbiranja zapisov v polja z uporabo razreda StringTokenizer.
 

Povzetek in izvorna koda

Ta enostavna metoda, ki smo jo opisali, je močan  način razbijanja nizov  v žetone. Če potrebujete bolj zahteven način razbiranja v žetone, bi si lahko raje pogledali razred StreamTokenizer.  Razred StreamTokenizer lahko prepozna različne stile komentarjev v programski kodi in ponuja veliko kontrolnih zastavic (control flags), ki jih lahko postavimo v  različna stanja(jim določimo različne vrednosti) in na osnovi teh vrednosti se potem razbija String-e v žetone.
 

Če želite podatkovno datoteko customer.db, potem  kliknite tukaj  in na isti način kot v prejšnjem odstavku shranite to datoteko v vaš sistem.

avtor: Kemal Posedi