Programovanie

Java Tip 112: Zlepšite tokenizáciu reťazcov bohatých na informácie

Väčšina programátorov v jazyku Java používa program java.util.StringTokenizer triedy v nejakom čase alebo inom. Je to šikovná trieda, ktorá v podstate tokenizuje (zlomí) vstupný reťazec na základe oddeľovača a na požiadanie dodá tokeny. (Tokenizácia je akt premeny sekvencií znakov na tokeny, ktorým váš program rozumie.)

Aj keď je to praktické, StringTokenizerfunkčnosť je obmedzená. Trieda jednoducho vyhľadá vo vstupnom reťazci oddeľovač a po nájdení oddeľovača reťazec rozbije. Nekontroluje podmienky, či je oddeľovač v podreťazci, ani nevráti token ako "" (dĺžka reťazca 0), akonáhle sa vo vstupe nájdu dva po sebe idúce oddeľovače. Na splnenie týchto obmedzení prichádza platforma Java 2 (JDK 1.2 a novšia) s BreakIterator triedy, čo je vylepšený tokenizer StringTokenizer. Pretože takáto trieda v JDK 1.1.x nie je, vývojári často trávia veľa času písaním originálneho tokenizátora, ktorý spĺňa ich požiadavky. Vo veľkom projekte zahŕňajúcom spracovanie dátových formátov nie je nezvyčajné nájsť veľa takýchto prispôsobených tried, ktoré plávajú okolo.

Tento tip si kladie za cieľ sprevádzať písaním sofistikovaného tokenizéra s využitím existujúceho StringTokenizer.

Obmedzenia StringTokenizer

Môžete vytvoriť StringTokenizer pomocou ktoréhokoľvek z nasledujúcich troch konštruktorov:

  1. StringTokenizer (String sInput): Prestávky na biele miesto ("", "\ t", "\ n").
  2. StringTokenizer (String sInput, String sDelimiter): Prestávky zapnuté sDelimiter.
  3. StringTokenizer (String sInput, String sDelimiter, boolean bReturnTokens): Prestávky zapnuté sDelimiter, ale ak bReturnTokens je nastavená na hodnotu true, potom sa ako token vráti aj oddeľovač.

Prvý konštruktér nekontroluje, či vstupný reťazec obsahuje podreťazce. Keď šnúrka "ahoj. Dnes \" idem \ "do môjho domovského mesta" je tokenizovaný na prázdnom mieste, výsledok je v tokenoch Ahoj., Dnes, „Ja, am, ", ísť, namiesto Ahoj., Dnes, "Som ", ísť.

Druhý konštruktér nekontroluje po sebe idúci vzhľad oddeľovačov. Keď reťazec „kniha, autor, publikácia ,,, dátum vydania“ je tokenizovaný dňa ",", StringTokenizer vráti štyri tokeny s hodnotami kniha, autor, publikáciaa dátum zverejnenia namiesto šiestich hodnôt kniha, autor, publikácia, "", ""a dátum zverejnenia, kde "" znamená reťazec dĺžky 0. Ak chcete získať šesť, musíte nastaviť StringTokenizerje bReturnTokens parameter na true.

Funkcia nastavenia parametra na true je dôležitá, pretože poskytuje predstavu o prítomnosti po sebe nasledujúcich oddeľovačov. Napríklad, ak sa údaje získavajú dynamicky a používajú sa na aktualizáciu tabuľky v databáze, kde sa vstupné tokeny mapujú na hodnoty stĺpcov, nemôžeme tokeny mapovať pomocou stĺpcov databázy, pretože si nie sme istí, ktoré stĺpce by sa mali nastaviť. do "". Napríklad chceme pridať záznamy do tabuľky so šiestimi stĺpcami a vstupné údaje obsahujú dva po sebe nasledujúce oddeľovače. Výsledok z StringTokenizer v tomto prípade je to päť tokenov (keďže dva po sebe nasledujúce oddeľovače predstavujú token "", ktoré StringTokenizer zanedbáva) a musíme nastaviť šesť polí. Tiež nevieme, kde sa objavuje následný oddeľovač, na ktorý stĺpec by sa mal nastaviť "".

Tretí konštruktor nebude fungovať, ak sa samotný token bude rovnať (dĺžkou a hodnotou) oddeľovaču a bude v podreťazci. Keď šnúrka "kniha, autor, publikácia, \", \ "dátum zverejnenia" je tokenizovaný (tento reťazec obsahuje , ako token, ktorý je rovnaký ako jeho oddeľovač) na reťazci ,, výsledok je kniha, autor, uverejnenie, ", ", dátum zverejnenia (so šiestimi žetónmi) namiesto kniha, autor, publikácia, , (znak čiarky), dátum zverejnenia (s piatimi žetónmi). Nezabudnite, dokonca aj nastavenie bReturnTokens (tretí parameter do StringTokenizer) na true vám v tomto prípade nepomôže.

Základné potreby tokenizéra

Predtým, ako začnete pracovať s kódom, musíte poznať základné potreby dobrého tokenizéra. Keďže vývojári Java sú zvyknutí na StringTokenizer triedy, dobrý tokenizer by mal mať všetky užitočné metódy, ktoré trieda poskytuje, ako napr hasMoreTokens (), nextToken (), countTokens ().

Kód tohto tipu je jednoduchý a väčšinou je vysvetľujúci. V zásade som použil StringTokenizer trieda (vytvorené pomocou bReturnTokens nastavená na hodnotu true) interne a poskytla metódy uvedené vyššie. Pretože v niektorých prípadoch je oddeľovač vyžadovaný ako tokeny (veľmi zriedkavé prípady), zatiaľ čo v iných nie, musí tokenizátor na požiadanie dodať oddeľovač ako token. Keď vytvoríte a PowerfulTokenizer objekt, ktorý odovzdáva iba vstupný reťazec a oddeľovač, interne používa a StringTokenizer s bReturnTokens nastavený na pravdivý. (Dôvodom je, ak a StringTokenizer je vytvorený bez bReturnTokens nastavená na hodnotu true, potom je obmedzená pri prekonávaní vyššie uvedených problémov). Pre správnu manipuláciu s tokenizérom kód skontroluje, či bReturnTokens je na niekoľkých miestach nastavený na hodnotu true (výpočet celkového počtu tokenov a nextToken ()).

Ako ste si mohli všimnúť, PowerfulTokenizer realizuje Vymenovanie rozhranie, čím sa implementuje hasMoreElements () a nextElement () metódy, ktoré jednoducho delegujú hovor na hasMoreTokens () a nextToken (), resp. (Implementáciou Vymenovanie rozhranie, PowerfulTokenizer stane sa spätne kompatibilným s StringTokenizer.) Zvážme príklad. Povedzme, že vstupný reťazec je „ahoj, dnes ,,, \" ja, idem ", idem ,,, \" kúpiť, a, kniha \ "" a oddeľovač je ,. Tento reťazec pri tokenizácii vracia hodnoty, ako je uvedené v tabuľke 1:

Tabuľka 1: Hodnoty vrátené tokenizovaným reťazcom
TypPočet tokenovŽetóny

StringTokenizer

(bReturnTokens = true)

19ahoj:,: Today:,:,:,: "I:,: am":,: chystám sa:,:,:,: "kúpiť:,: a:,: kniha" (tu postava : oddeľuje žetóny)

PowerfulTokenizer

(bReturnTokens = true)

13ahoj:,: Today:,: "": "": I, am:,: chystám sa:,: "": "": kúpiť knihu (kde "" znamená reťazec dĺžky 0)

PowerfulTokenizer

(bReturnTokens = false)

9ahoj: dnes: "": "": chystám sa: "": "": kúpiť si knihu

Vstupný reťazec obsahuje 11 čiarok (,) znaky, z ktorých tri sú vnútri podreťazcov a štyri sa objavujú postupne (ako Dnes ,,, robí dve po sebe nasledujúce čiarky, prvá je čiarka Dnesoddeľovač). Tu je logika pri výpočte počtu tokenov v PowerfulTokenizer prípad:

  1. V prípade bReturnTokens = true, vynásobte počet oddeľovačov vo vnútri podreťazcov 2 a odčítajte túto sumu od skutočného súčtu, aby ste získali počet tokenov. Dôvod je pre podreťazec „kúpiť, rezervovať“, StringTokenizer vráti päť žetónov (t.j. kúpiť:,: a:,: kniha), zatiaľ čo PowerfulTokenizer vráti jeden token (tj. kúpiť, a, rezervovať). Rozdiel sú štyri (tj. 2 * počet oddeľovačov vo vnútri podreťazca). Tento vzorec platí pre akýkoľvek podreťazec obsahujúci oddeľovače. Majte na pamäti špeciálny prípad, keď sa samotný token rovná oddeľovaču; toto by nemalo znižovať hodnotu počtu.
  2. Podobne pre prípad bReturnTokens = false, od skutočnej sumy (19) odčítajte hodnotu výrazu [celkové oddeľovače (11) - po sebe idúce oddeľovače (4) + počet oddeľovačov vo vnútri podreťazcov (3)], aby ste získali počet tokenov. Pretože v tomto prípade nevraciame oddeľovače, sú pre nás (bez toho, aby sa vyskytli postupne alebo vo vnútri podreťazcov) k ničomu a vyššie uvedený vzorec nám dáva celkový počet tokenov (9).

Pamätajte na tieto dva vzorce, ktoré sú srdcom PowerfulTokenizer. Tieto vzorce fungujú takmer pre všetky príslušné prípady. Ak však máte zložitejšie požiadavky, ktoré nie sú vhodné pre tieto vzorce, musíte pred tým, ako sa pustíte do programovania, zvážiť rôzne príklady, aby ste si vytvorili svoj vlastný vzorec.

 // skontrolovať, či je oddeľovač v podreťazci pre (int i = 1; i

The nextToken () metóda získava tokeny pomocou StringTokenizer.nextTokena skontroluje, či je v tokene znak dvojitej úvodzovky. Ak metóda tieto znaky nájde, získa viac tokenov, kým nenájde žiadne s dvojitou úvodzovkou. Ukladá tiež token do premennej (sPrevToken; pozri zdrojový kód) na kontrolu po sebe idúcich vystúpení oddeľovača. Ak nextToken () nájde po sebe idúce tokeny, ktoré sa rovnajú oddeľovaču, potom sa vráti "" (reťazec s dĺžkou 0) ako token.

Podobne hasMoreTokens () metóda kontroluje, či je počet požadovaných tokenov menší ako celkový počet tokenov.

Ušetrite čas na vývoj

Tento článok vás naučil, ako ľahko napísať výkonný tokenizer. Pomocou týchto konceptov môžete rýchlo písať zložité tokenizátory, čo vám ušetrí značný čas na vývoj.

Bhabani Padhi je architekt a programátor v prostredí Java, ktorý v súčasnosti pracuje na vývoji webových a podnikových aplikácií pomocou technológie Java v austrálskom UniteSys. Predtým pracoval v spoločnosti Baltimore Technologies v Austrálii na vývoji produktov elektronickej bezpečnosti a v spoločnosti Fujitsu v Austrálii na projekte vývoja serverov EJB. Medzi záujmy spoločnosti Bhabani patrí vývoj distribuovaných počítačov, mobilných aplikácií a webových aplikácií pomocou technológie Java.

Získajte viac informácií o tejto téme

  • Získajte zdrojový kód tohto tipu

    //images.techhive.com/downloads/idge/imported/article/jvw/2001/06/powerfultokenizer.java

  • Viac informácií o BreakIterator

    //java.sun.com/products/jdk/1.2/docs/api/java/text/BreakIterator.html

  • Zobraziť všetky predchádzajúce Tipy pre Java a odovzdať svoje vlastné

    //www.javaworld.com/javatips/jw-javatips.index.html

  • Pre viac Úvodná úroveň články, navštívte JavaWorld 's Aktuálny index

    //www.javaworld.com/javaworld/topicalindex/jw-ti-introlevel.html

  • Naučte sa Java od základu v JavaWorld 's Java 101 stĺpec

    //www.javaworld.com/javaworld/topicalindex/jw-ti-java101.html

  • Odborníci na jazyk Java odpovedajú na vaše najťažšie otázky týkajúce sa jazyka Java v jazyku JavaWorld 's Java Q&A stĺpec

    //www.javaworld.com/javaworld/javaqa/javaqa-index.html

  • Zaregistrujte sa do JavaWorld tento týždeň bezplatný týždenný e-mailový bulletin a zistíte, čo je nové JavaWorld

    //www.idg.net/jw-subscribe

Tento príbeh, „Java Tip 112: Improve tokenization of information-rich strings“, bol pôvodne publikovaný spoločnosťou JavaWorld.

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