SCJP - Tokenizacja tekstu
Tokenizacja to proces w wyniku którego monolityczny tekst zostaje podzielony na ciąg pojedynczych tokenów. Tokeny to ciągi znaków ograniczone ustalonymi separatorami takimi jak spacje czy przecinki, aczkolwiek separatorem może być dowolny ciąg który da się opisać w postaci wyrażenia regularnego. Najbardziej elementarny algorytm tokenizacji w Javie implementuje metoda split(…) z klasy String. Metoda ta dokonuje podziału tekstu reprezentowanego przez obiekt dla którego została wywołana używając separatora opisanego wyrażeniem regularnym przekazanym jako argument wywołania. Przykład poniżej:
public void tokenize() {
String[] tokens = "dowolny tekst do tokenizacji".split("\\s");
for(String token : tokens)
System.out.println(token);
}
Wyrażenie regularne \s (które musimy zapisać jako \\s) oznacza biały znak (ang. whitespace character), tj. spacje, tabulacje, znaki nowej linii itd. Uruchomienie powyższej metody spowoduje więc wyświetlenie napisu:
dowolny
tekst
do
tokenizacji
Bardziej wyrafinowanych mechanizmów tokenizacji dostarcza klasa Scanner z pakietu java.util. Zasadnicza różnica w stosunku do metody split(…) polega na tym, że tokenizowany tekst jest przetwarzany stopniowo, w miarę potrzeby, i proces może być w dowolnej chwili zaniechany. Skanerem posługujemy się jak iteratorem. Klasa Scanner implementuje interfejs java.util.Iterator
public Scanner(String source)
public Scanner(File source) throws FileNotFoundException
public Scanner(InputStream source)
Identyczna funkcjonalnie metoda jak pokazana w pierwszym przykładzie, tyle że zaimplementowana przy użyciu skanera mogłaby więc wyglądać następująco:
public void tokenize() {
Iteratorscanner = new Scanner("dowolny tekst do tokenizacji");
while (scanner.hasNext())
System.out.println(scanner.next());
}
W powyższym przykładzie nie określono separatora i w takim wypadku skaner używa separatora domyślnego jakim są białe znaki; stąd równoważność funkcjonalna z przykładem używającym metody split(…). Aby ustawić separator – opisany jako wyrażenie regularne – należy użyć metody useDelimiter(…) co pokazano poniżej:
public void tokenize() {
Scanner scanner = new Scanner("dowolny tekst do tokenizacji");
scanner.useDelimiter("\\s");
while (scanner.hasNext())
System.out.println(scanner.next());
}
Oprócz metod hasNext() i next() pochodzących z interfejsu Iterator
public int sum() {
Scanner scanner = new Scanner("a 1 b 2 c 3 d e f");
int sum = 0;
while (scanner.hasNext()) {
if (scanner.hasNextInt()) {
sum += scanner.nextInt();
} else {
System.out.println("nie int: " + scanner.next());
}
}
return sum;
}
1 komentarz:
Dobre, szczególnie ten ostatni przykład. Pewnie, gdybym dostał go na egzaminie, to stwierdziłbym, że zostanie zgłoszony wyjątek. Interesujące.
Prześlij komentarz