47
Wyjątki Operacje na napisach (klasy String, StringTokenizer, StringBuffer, StringBuilder ) Treści prezentowane w wykładzie zostały oparte o: Barteczko, JAVA Programowanie praktyczne od podstaw, PWN, 2014 Barteczko, JAVA Uniwersalne techniki programowania, PWN, 2017 http://docs.oracle.com/javase/8/docs/ C. S. Horstmann, G. Cornell, Java. Podstawy, Helion, Gliwice 2013 Programowanie w środowisku graficznym- wykład 4

Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

WyjątkiOperacje na napisach (klasy String, StringTokenizer, StringBuffer, StringBuilder )

Treści prezentowane w wykładzie zostały oparte o:● Barteczko, JAVA Programowanie praktyczne od podstaw, PWN, 2014● Barteczko, JAVA Uniwersalne techniki programowania, PWN, 2017● http://docs.oracle.com/javase/8/docs/● C. S. Horstmann, G. Cornell, Java. Podstawy, Helion, Gliwice 2013

Programowanie w środowisku graficznym- wykład 4

Page 2: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

2

WYJĄTKI

Wyjątek - to sygnał o błędzie w trakcie wykonania programu

● Wyjątek powstaje na skutek jakiegoś nieoczekiwanego błędu.

● Wyjątek jest zgłaszany (lub mówiąc inaczej - sygnalizowany).

● Wyjątek jest (może lub musi być) obsługiwany.

Prosty schemat obsługi wyjątków

try { // ... w bloku try ujmujemy instrukcje, //które mogą spowodować wyjątek } catch(TypWyjatku exc) { //w klauzuli catch umieszczamy obsługę wyjątku } catch (TypWyjatku2 exc) {

//obsługa wyjątków TypWyjatku2

} catch (TypWyjatku3 w) {

//obsługa wyjątków TypWyjatku3 } ...

Page 3: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

3

WYJĄTKI● Wykonywane są kolejne instrukcje bloku try.

● Jeśli w pewnej instrukcji wystąpi błąd (na skutek czego powstanie wyjątek), wykonanie bloku try jest przerywane w miejscu wystąpienia błędu.

● Sterowanie przekazywane jest do pierwszej w kolejności klauzuli catch, w której podana w nawiasach okrągłych po słowie catch klasa wyjątku pasuje do typu powstałego wyjątku. Inne klauzule catch nie są wykonywane.

● Stąd ważny wniosek: najpierw podawać BARDZIEJ SZCZEGÓŁOWE TYPY WYJĄTKÓW np. najpierw FileNotFoundException, a później IOException, bo klasa FileNotFoundException jest pochodna od IOException

● Obsługująca wyjątek klauzula catch może zrobić wiele rzeczy: m.in. zmienić sekwencję sterowania (np. poprzez return lub zgłoszenie nowego wyjątku za pomocą instrukcji throw). Jeśli nie zmienia sekwencji sterowania, to wykonanie programu jest kontynuowane od następnej instrukcji po bloku try.

Page 4: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

4

WYJĄTKI

PRZYKŁAD. Przypadek braku jawnej obsługi wyjątku dzielenia przez 0

public class NoCatch { public static void main(String[] args) {

int a = 1, b = 0, c = 0;

c = a/b;

System.out.println(c); }}

- powstały błąd (wyjątek) powoduje zakończenie programu, a JVM wypisuje komunikat o jego przyczynie:

Exception in thread "main" java.lang.ArithmeticException: / by zero at NoCatch.main(NoCatch.java:6)

Page 5: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

5

WYJĄTKIPRZYKŁAD 2. Obsługa wyjątku ArithmeticException - zabezpieczenie się przed możliwymi skutkami całkowitoliczbowego dzielenia przez zero

public class Catch1 { public static void main(String[] args) {

int a = 1, b = 0, c = 0;

String wynik;

try {

c = a/b;//spowoduje powstanie wyjątku

wynik = "" + c;

} catch (ArithmeticException exc) {

wynik = "Dzielenie przez zero"; }

System.out.println(wynik);

}}

Page 6: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

6

WYJĄTKI

● Typowym przykładem obsługi wyjątków jest weryfikacja wprowadzanych przez użytkownika w oknach dialogowych danych. W omawianych poprzednio przykładowych programach żądaliśmy od użytkownika wprowadzania liczb całkowitych, a następnie za pomocą metody parseInt przekształcaliśmy ich znakową reprezentację na binarną. Jak wiemy, jeśli przy tym wprowadzony napis nie reprezentuje liczby całkowitej, to powstaje wyjątek NumberFormatException. Powinniśmy go zawsze obsługiwać.

● Możemy więc teraz zmodyfikować np. program wykonywania operacji arytmetycznych na liczbach całkowitych:

try {

int num1 = Integer.parseInt(snum1); //operacje na num1 } catch (NumberFormatException exc) {

//obsługa wyjątku }

Page 7: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

7

WYJĄTKI -przykład

public class CatchTest {

public static Integer pobierzInteger() { String wynik; while((wynik = javax.swing.JOptionPane.showInputDialog( "Podaj liczbę całkowitą"))!=null){ try {

return Integer.parseInt(wynik);//jest liczba

} catch(NumberFormatException exc) {}//błędna wartość //nie robimy nic, powrót do while i ponowna próba pobrania } return null;//Anulowano }

public static void main(String[] args) {

Integer i = pobierzInteger(); if (i == null) System.out.println("Anulowano"); else System.out.println("Podano: " + i); }}

Page 8: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

8

WYJĄTKI

● Wyjątki są obiektami klas wyjątków.

● Zatem nazwy np. NumberFormatException są nazwami klas, a zmienna exc zawiera referencję do obiektu odpowiedniej klasy wyjątku. Wobec tej zmiennej możemy użyć licznych metod klas wyjątków np.

– getMessage()- zwraca napis - informację o wyjątku

– toString() - zwraca napis - informację o wyjątku (zazwyczaj nazwę klasy + dodatkowe informacje uzyskane przez getMessage())

– printStackTrace()- wypisuje na konsoli informacje o wyjątku oraz sekwencje wywołań metod, które doprowadziły do wyjątku (stos wywołań)

– getCause() - zwraca wyjątek niższego poziomu, który spowodował powstanie wyjątku lub null w przeciwnym razie

Page 9: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

9

WYJĄTKI

● W Javie zdefiniowanych jest wiele typowych wyjątków (najważniejsze są w pakiecie java.lang). Są one używane przez klasy ze standardowych bibliotek. Różnią się jedynie nazwą, która pozwala zorientować się co dany wyjątek oznacza. W swoich aplikacjach można korzystać z tych klas lub zdefiniować nowe, pasujące do konkretnego zastosowania. Wszystkie klasy, których egzemplarze mogą być zgłoszone jako wyjątek muszą dziedziczyć po klasie Throwable.

● Throwable ma dwie bezpośrednie podklasy Error i Exception. Wyjątki dziedziczące po Error reprezentują poważne problemy, których aplikacja nie będzie w stanie rozwiązać. Przykładową podklasą jest VirtualMachineError. Wystąpienie takiego wyjątku oznacza, że maszyna wirtualna nie może dalej kontynuować pracy, np. z powodu wyczerpania się zasobów systemowych. Wyjątków rozszerzających Error nie należy przechwytywać, gdyż nie ma możliwości zaradzenia sytuacjom wyjątkowym, które je spowodowały.

Page 10: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

10

WYJĄTKI – Klasa Exception● Wyjątki dziedziczące po Exception reprezentują sytuacje, na które

aplikacja powinna być przygotowana. Jej przykładowe podklasy to:

– IOException, która reprezentuje sytuacje wyjątkowe związane z wejściem/wyjściem,

– ClassNotFoundException, która wskazuje, że maszyna wirtualna nie odnalazła klasy o nazwie podanej jako napis.

● Ciekawą podklasą Exception jest RuntimeException. Wyjątki rozszerzające RuntimeException mogą wystąpić podczas typowych operacji, jak rzutowanie zmiennej, odwołanie się do elementu tablicy lub odwołanie się do składowej obiektu. Ich wystąpienie zazwyczaj oznacza, że programista popełnił błąd w swoim kodzie. JVM wykrywa wystąpienie takich błędów w trakcie działania programu i informuje o tym, zgłaszając odpowiedni wyjątek. Mimo, że takie wyjątki też można obsługiwać, zdecydowanie lepiej jest zadbać, żeby się nie pojawiały. Ze względu na swoją wszechobecność ich pełna obsługa praktycznie mijałaby się z celem.

Page 11: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

11

WYJĄTKI● Wyjątki pochodne od klas RuntimeException i Error są

niekontrolowane – nie muszą być obsługiwane.

● Pozostałe wyjątki są kontrolowane, co oznacza, że: metody zgłaszają wyjątki wymienione jawnie w swojej klauzuli throws (ew. podklasy tych wyjątków). Wówczas odwołania do tych metod wymagają jawnej obsługi ewentualnie zgłaszanych wyjątków poprzez konstrukcje try – catch lub poprzez wymienienie wyjątku w klauzuli throws naszej metody (tej która odwołuje się do metody, która może zgłosić wyjątek) i "przesunięcie" obsługi wyjątku do miejsca wywołania naszej metody.

● Zatem wiele razy natkniemy się na sytuację, w której musimy obsługiwać wyjątki, które mogą powstać przy wywołaniu jakichś metod ze standardowych klas Javy. Jeśli tego nie zrobimy, kompilator wykaże błąd w programie. Sytuacja taka dotyczy, np. metod ze standardowego pakietu java.io, zawierającego klasy do operowania na strumieniach danych (m.in. plikach).

● Deklaracja throws TypWyj1, TypWyj2,..., TypWyjNużywana w nagłówku metody, konstruktora, oznacza że dana metoda może zgłaszać wyjątki podanych typów:public void metoda() throws InterruptedException{// ciało metody- tu może powstać wyjątek}

Page 12: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

12

KLAUZULA FINALLYKlauzula finally służy do wykonania kodu niezależnie od tego czy wystąpił wyjątek czy nie.boolean metoda(...) {

try { // instrukcje, które mogą spowodować wyjątek } catch(Exception e) { return false; }

finally {

// posprzątanie, np. zamknięcie pliku } return true; }Jeśli powstał wyjątek - wykonywana jest klauzula catch. Mimo, iż zmienia ona sekwencję sterowania (zwraca false na znak, iż nastąpiło niepowodzenie), sterowanie przekazywane jest do klauzuli finally. I dopiero potem zwracany jest wynik - false. Jeśli nie było wyjątku, po zakończeniu instrukcji w bloku try sterowanie od razu wchodzi do klauzuli finally, a po jej zakończeniu zwracany jest wynik true (wykonywana jest ostatnia instrukcja metody). Dopuszczalna jest forma try bez catch, ale z finally.

Page 13: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

13

multicatch

Wprowadzony w Javie 7 mulitcatch upraszcza obsługę wyjątków. Zamiast:

try { //kod, w którym może powstać jeden z wyjątków //TypExc1, TypExc2}catch (TypExc1 exc){ func();}catch (TypExc2 exc){ func();}

możemy zapisać jedną klauzulę catch dla kilku typów wyjątków

try{ //kod, w którym może powstać jeden z wyjątków //TypExc1, TypExc2}catch (TypExc1 | TypExc2 exc){ func();}

Oczywiście, ma to sens wtedy, gdy obsługa wyjątków TypExc1 , TypExc2 jest taka sama i nie da się jej wyrazić poprzez przechwycenie wyjątku wspólnej nadklasy.

Page 14: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

14

try-with-resources

Podobnie, od Javy 7 zamiast pisać:

try { FileInputStream in = new FileInputStream("plik"); try { FileOutputStream out = new FileOutputStream("cel"); //Działanie na "in" i "out" } finally { if(out != null){out.close();} } } finally { if(in!= null){in.close();} }

dla obiektów klas implementujących interfejs AutoCloseable (np. klasy FileInputStream i FileOutputStream), można użyć konstrukcji "try-with-resources":

try (FileInputStream in = new FileInputStream("plik"); FileOutputStream out = new FileOutputStream("cel")) { //Działanie na "in" i "out"}

Page 15: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

15

WŁASNE WYJĄTKI

Aby stworzyć własny wyjątek należy zdefiniować odpowiednią klasę dziedziczącą po klasie Exception:

class NaszWyj extends Exception {…}

Zwykle w naszej klasie wystarczy umieścić dwa konstruktory: bezparametrowy oraz z jednym argumentem typu String (komunikat o przyczynie powstania wyjątku). W konstruktorach tych należy wywołać konstruktor nadklasy (za pomocą odwołania super(...), w drugim przypadku z argumentem String).

Jeśli jakaś nasza metoda ma sygnalizować wyjątek NaszWyj - musi podać w deklaracji, że może to zrobić:

void naszaMetoda() throws NaszWyj

a następnie sprawdza warunki powstania błędu i jeśli jest błąd - tworzy wyjątek (new NaszWyj(...)) i sygnalizuje go za pomocą instrukcji throw :

throw new NaszWyj(ew_param_konstruktora_z_info_o_błędzie)

Page 16: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

16

WŁASNE WYJĄTKIclass NaszWyjatek extends Exception { //klasa wyjątku NaszWyjatek() {super();} //konstruktory NaszWyjatek(String s) { super(s); }}

public class NaszaKlasa { … public void metoda() throws NaszWyjatek { … throw new NaszWyjatek("Jakaś przyczyna"); … } …}-------------------------------------------------public class NowyWyjatekTest { public static void main(String[] args) { NaszaKlasa obj = new NaszaKlasa(); try { obj.metoda(); } catch (NaszWyjatek w) { System.out.println(w.getMessage()); //nadklasa Throwable, definiuje metodę getMessage(), //przy pomocy której można wydobyć napis z wyjątku } }}

Page 17: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

17

Klasa String● W klasie String znajdziemy wiele użytecznych metod przeznaczonych do

operowania na łańcuchach znakowych.

● Kolejne znaki napisów występują na pozycjach, które są indeksowane od 0.

● Części napisów (łańcuchów znakowych) określa się terminem "podłańcuch" (substring).

● Obiekty klasy String są niemodyfikowalne (ang. immutable) - to znaczy napisów klasy String nie możemy zmieniać (np. do napisu dodać inny). W wielokrotnie używanej przez nas konkatenacji łańcuchów wynikowy napis, powstający z dodania do łańcucha znakowego innego napisu, jest nowym obiektem i np. w takiej sekwencji:String s = "Ala";s = s + " ma kota";tworzony jest nowy obiekt, zawierający napis "Ala ma kota" i referencja do niego przypisywana jest zmiennej s, która poprzednio zawierała referencję do napisu "Ala".

● Zwróćmy też uwagę, że w klasie String nie ma żadnych metod pozwalających modyfikować istniejący obiekt-napis.

Page 18: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

18

Klasa String -wybrane metody

Poniżej przedstawimy kilka wybranych metod. Większość metod (wszystkie metody niestatyczne) używana jest "na rzecz" obiektów klasy String; o obiekcie na rzecz którego wywołano metodę mówimy ten napis.

● String(char[] c) – konstruktor, tworzy napis z tablicy znakówchar data[] = {'a', 'b', 'c'};String str = new String(data);

● String(byte[] b) – konstruktor, tworzy napis z tablicy bajtów (używana jest domyślna strona kodowa do przekształcania bajtów na znaki)

● char charAt(int index) - zwraca znak na pozycji, oznaczonej indeksem index. Pierwsza pozycja ma indeks 0.

● int compareTo(String anotherString) - porównuje dwa napisy: ten (this) na rzecz którego użyto metody oraz przekazany jako argument.Metoda zwraca 0, gdy napisy są takie same.Jeżeli się różnią, to - gdy występują w nich różne znaki - zwracana jest wartość:this.charAt(k) - anotherString.charAt(k), gdzie k - indeks pierwszej pozycji, na której występuje różnica znaków. Jeżeli długość napisów jest różna (a znaki napisów są takie same w części określanej przez długość krótszego napisu) - zwracana jest różnica długości: this.length() - anotherString.length(). Oznacza to, że wynik jest ujemny, gdy ten (this) łańcuch poprzedza leksykograficznie (alfabetycznie) argument (anotherString) oraz dodatni - gdy ten łańcuch jest leksykograficznie większy od argumentu.

Page 19: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

19

Klasa String -wybrane metody● int compareToIgnoreCase(String str) - porównuje leksykograficznie dwa

napisy, bez rozróżnienia małych i wielkich liter.

● boolean endsWith(String suffix) - zwraca true, gdy napis kończy się łańcuchem znakowym podanym jako argument, false - w przeciwnym razie.

● boolean equals(Object anObject) - zwraca true, gdy anObject jest takim samym co do zawartości napisem jak ten napis; w każdym innym przypadku - zwraca false.

● boolean equalsIgnoreCase(String anotherString) - j.w. - ale bez rozróżniania małych i wielkich liter.

● byte[] getBytes() zwraca tablicę bajtów reprezentujących ten napis w domyślnej stronie kodowej

String example = "This is an example";byte[] bytes = example.getBytes();try { byte[] utf8Bytes = example.getBytes("UTF8"); System.out.println("Text UTF8: " + utf8Bytes);//[B@7852e922} catch (UnsupportedEncodingException ex) { ex.printStackTrace();}System.out.println("Text: " + bytes);//[B@4e25154f

Page 20: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

20

Klasa String -wybrane metody

● int indexOf(String str) - zwraca indeks pozycji pierwszego wystąpienia w danym napisie napisu podanego jako argument str; jeżeli str nie występuje w tym napisie - zwraca -1

String str = "Welcome home";

System.out.println(str.indexOf( 'o' )); //4

● int indexOf(String str, int fromIndex)- poszukuje pierwszego wystąpienia napisu str poczynając od pozycji oznaczonej przez indeks fromIndex; zwraca indeks pozycji na której zaczyna się str lub -1 gdy str nie występuje w tym napisie.

System.out.println(str.indexOf( 'o' ,5)); //9

● int lastIndexOf(String str) - jak indexOf - ale zwracany jest indeks pozycji ostatniego wystąpienia

System.out.println(str.lastIndexOf( 'e' ));//11

● int length() - zwraca długość napisu

● String replace(char oldChar, char newChar) - zwraca nowy obiekt klasy String, w którym zastąpiono wszystkie wystąpienia znaku oldChar na znak newChar.

System.out.println(str.replace('h', 'H')); //Welcome Home

Page 21: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

21

Klasa String -wybrane metody

● boolean startsWith(String prefix)- zwraca true, gdy napis zaczyna się podanym jako argument łańcuchem znakowym; false - w przeciwnym razie.

String str = "Welcome home";

System.out.println(str.startsWith("Welc") );//true

● String substring(int beginIndex) - zwraca podłańcuch tego łańcucha znakowego zaczynający się na pozycji o indeksie beginIndex (do końca łańcucha)

String s="hello";

System.out.println(s.substring(2));//llo

● String substring(int beginIndex, int endIndex) - zwraca podłańcuch tego łańcucha jako nowy obiekt klasy String. Podłańcuch zaczyna się na pozycji o indeksie beginIndex, a kończy (uwaga!) - na pozycji o indeksie endIndex-1. Długość podłańcucha równa jest endIndex – beginIndex.

String s2 = "abcde".substring(2,3);

System.out.println(s2);//c

● char[] toCharArray()- znaki łańcucha -> do tablicy znaków (typ char[]).

Page 22: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

22

Klasa String -wybrane metody

● String toLowerCase() - zamiana liter na małe.

System.out.println("HELLO".toLowerCase());//hello

● String toUpperCase() - zamiana liter na duże.

System.out.println("Hello".toUpperCase());//HELLO

● String trim() - usuwa znaki spacji, tabulacji, końca wiersza itp. tzw. białe znaki z obu końców łańcucha znakowego. Zwraca wynik jako nowy łańcuch.

System.out.println(" Ala ma kota ".trim());//Ala ma kota

● static String valueOf(char c) - zwraca wartość typu char jako napis.

● static String valueOf(char[] data) - zwraca napis złożony ze znaków z tablicy.

String s3= String.valueOf(new char[]{'a','l','a'});

System.out.println(s3); //ala

● static String valueOf(double d) - zwraca znakową reprezentację liczby typu double.

● static String valueOf(int i) - zwraca znakową reprezentację liczby typu int.

Page 23: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

23

Klasa String● Uwaga. Zanim napiszemy fragment wykonujący określone zadanie na

napisach, sprawdźmy w dokumentacji czy w klasie String nie ma metod, które by nam to ułatwiły.

● Kiedy porównujemy jakieś napisy, to zwróćmy uwagę na

– Czy białe znaki (spacje, tabulacje) ewentualnie okalające napis są istotne w porównaniu; jeśli nie to użyjmy metody trim()

– Czy chcemy porównać napisy, uwzględniając wielkość liter; jeśli nie, to użyjmy metod equalsIgnoreCase lub ujednolićmy wielkość liter w napisach metodami toUpperCase()lub toLowerCase()

● Przykład. Użytkownik odpowiada w dialogu wejściowym na pytanie. Uwzględnijmy to, że może wprowadzić niepotrzebne spacje lub użyć różnej wielkości liter.String ans=JOptionPane.showInputDialog ("Czy mam wykonać program?");if (ans != null){ ans=ans.trim().toUpperCase(); switch(ans){ case "TAK": case "T" : execute(); }}

Page 24: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

24

String – metoda join

● W Javie 8 do klasy String dodano metody statyczne

join(separator, zestaw_napisów)

gdzie zestaw_napisów to albo argumenty-napisy oddzielone przecinkami, albo tablica napisów, albo kolekcja napisów. Metoda wstawia podany separator między elementy zestawu_napisów i zwraca tak utworzony String:

● Przykład: String res= String.join("-", "A", "B", "C"); System.out.println(res); //A-B-C

int n=10;

String[] stab = new String[n];

int sum=0;

for (int i=1; i<=n; i++){ sum+=i; stab[i-1]=String.valueOf(i); }

System.out.println(String.join("+",stab)+" = "+sum); //1+2+3+4+5+6+7+8+9+10 = 55

Page 25: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

25

String - przykład 1import javax.swing.*;

public class Wycieczki {

public static void main(String[] args) {

String[] dest = {"Bali", "Cypr", "Ibiza", "Kenia", "Kuba"};

double[] price = {5000, 2500, 2800, 4500, 6000};

String msg = "Wybierz kierunek - " +

" wpisując literę A-"+ (char) ('A'+dest.length-1)+ ":\n";

for (int i=0; i < dest.length; i++)

msg += (char) ('A' + i) + " - " + dest[i] + '\n';

String res;

while ((res = JOptionPane.showInputDialog(msg)) != null) {

if (res.length() == 0) continue;

int i = res.charAt(0) - 'A';

if (i < 0 || i >= dest.length) continue;

JOptionPane.showMessageDialog(null, dest[i] + " - cena: " + price[i]); } }}

Page 26: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

26

String - przykład 2

public class ZnajdzAnd{public static void main(String[] args) { // Tekst do analizy String text = "To be or not to be, that is the question;" + " Whether 'tis nobler in the mind to suffer" + " the slings and arrows of outragous fortunę," + " or to take arms against a sea of troubles," + " and by opposing end them?"; int licznikAnd = 0;// liczy wystąpienia and String andStr = "and"; // podłańcuch do wyszukania int index = text.indexOf(andStr); // pierwsze and while(index >= 0) { ++licznikAnd; index += andStr.length() ; //przeskocz do pozycji //po pierwszym znalezionym and index = text.index0f(andStr, index); } } System.out.println("Tekst zawiera " + licznikAnd + " and");}

Page 27: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

27

StringBuffer, StringBuilder

● Modyfikowalne obiekty-łańcuchy definiują klasy StringBuffer i StringBuilder

● Klasa StringBuilder ma takie same metody jak StringBuffer.

● Rożnica między klasami StringBuffer i StringBuilder polega tylko na tym, że pierwsza zapewnia synchronizację dostępu z równolegle wykonujących się fragmentów kodu (wątków), a wobec tego jest trochę mniej efektywna; jednak ta właściwość jest niezbędna w programowaniu współbieżnym.

● Zastosowanie klasy StringBuffer lub StringBuilder zamiast String jest wskazane przy dużej liczbie połączonych operacji konkatenacji, bo dzięki temu uzyskujemy wielokrotnie wyższą efektywność działania programu. (Przy naprawdę dużej liczbie – powyżej ok. 50 tys.-operacji np. w pętli, użycie klasy String i operatora + jest niedopuszczalne)

Page 28: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

28

StringBuffer, StringBuilder

Obiekty klasy StringBuffer oraz StringBuilder , to "bufory"-przydzielone fragmenty pamięci, które dynamicznie możemy wypełniać napisami. Łańcuch może też zajmować tylko część bufora. W szczególności możemy utworzyć pusty - na razie - bufor:

StringBuffer sb = new StringBuffer();//StringBuilder sb = new StringBuilder();

po czym wypełniać go zawartością dopisując do niego jakieś kolejne napisy:

sb.append("jakiś napis 1");sb.append(10);sb.append(new Para(1,2));

Metoda append zwraca StringBuffer, wobec tego możemy zapisać krócej

sb.append("jakiś napis 1").append(10).append(new Para(1,2));

Jeśli utworzyłeś już obiekt StringBuffer możesz sprawdzić jego długość metodą length() oraz pojemność metodą capacity().

Nie musisz przejmować się pojemnością bufora, w razie potrzeby zostanie ona automatycznie zwiększona.

Page 29: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

29

StringBuffer, StringBuilder● Możesz zdefiniować obiekt StringBuffer o zadanej pojemności startowej

StringBuffer tekstBufor = new StringBuffer(50);Domyślnie nowy obiekt StringBuffer mieści 16 znaków.

● Możesz też zmieniać długość obiektu StringBuffer. Jeśli mamyStringBuffer tekstBufor = new StringBuffer("Jakiś tekst");to po poleceniu

tekstBufor.setLength(5);

tekstBufor zawiera "Jakiś". Możemy wrócić do poprzedniej długości obiektu tekstBufor przez

tekstBufor.setLength(ll);

ale zawarty tam tekst już zginął. Nie wolno ustawiać ujemnej długości. Jeśli tak zrobisz zostanie zgłoszony wyjątek StringOutOfBoundsException,

● Obiekt klasy StringBuffer łatwo można przekształcić w obiekt klasy String za pomocą metody toString(): String s = sb.toString();

Page 30: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

30

StringBuffer, StringBuilder

● Do wstawiania łańcuchów do obiektów StringBuffer służy metoda insert() StringBuffer przyslowie = new StringBuffer("Bez pracy nie ma kołaczy"); przyslowie.insert(4,"dobrej ");wstawi poczynając od indeksu 4 łańcuch "dobrej ". Zatem przyslowie będzie zawierać "Bez dobrej pracy nie ma kołaczy". Ta wersja metody insert dopuszcza jako drugi argument dowolny z typów, które dopuszcza metoda append. Można też wstawiać tablice typu char[].

● StringBuffer zawiera metody charAt() i getChars(), które działają tak jak metody klasy String, Metoda charAt() pobiera znak z zadanej pozycji, a metoda getChars() pobiera ciąg znaków i umieszcza go w tablicy typu char poczynając od zadanej pozycji. Nie ma analogonu metody getBytes() dla obiektów StringBuffer,

● Możesz zmieniać konkretny znak na danej pozycji:przyslowie.setCharAt(2,"z");

● Możesz odwrócić kolejność znaków w łańcuchu:StringBuffer palindrom = new StringBuffer("wspak"); palindrom.reverse();//Wtedy palindrom zawiera "kapsw".

Page 31: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

31

Rozbiór tekstów - StringTokenizer

● Bardzo często w programowaniu występują sytuacje, gdy trzeba rozbić, rozłożyć(dokonać analizy) jakiś tekst (napis) na poszczególne występujące w nim symbole (np. słowa, liczby). Symbolem nazywamy dowolny ciąg znaków który nie zawiera separatora.

● Do wyłuskiwania symboli z łańcuchów znakowych służy m.in. klasa StringTokenizer z pakietu java.util.

● Po to by dokonać rozbioru tekstu - tworzymy obiekt klasy StringTokenizer, podając jako argument konstruktora - tekst do rozbioru np.String expr = "21 + 21";StringTokenizer st = new StringTokenizer(expr);

● Ta postać konstruktora zakłada domyślnie, że separatorami są znaki z następującego zestawu " \t\n\r\f" (czyli znak spacji, tabulacji, przejścia do nowego wiersza, powrotu karetki, nowej strony). W tym przypadku symbolami będą ciągi znaków, które nie zawierają żadnego z wymienionych separatorów

Page 32: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

32

Rozbiór tekstów - StringTokenizer

● Obiektu klasy StringTokenizer możemy teraz zapytać o to ile elementów zawiera przekazany konstruktorowi napis: int n = st.countTokens(); // n = 3 ("21 + 21")

● Wyłuskiwanie elementów odbywa się sekwencyjnie poczynając od początku łańcucha. Służy temu metoda nextToken(), która zwraca kolejny element jako String. String s1 = st.nextToken(); // napis "21" String s2 = st.nextToken(); // napis "+" String s3 = st.nextToken(); // napis "21"

● Gdy nie ma już elementów "do zwrotu" - wywołanie nextToken() spowoduje powstanie wyjątku NoSuchElementException.

● Do stwierdzenia, czy w łańcuchu znakowym są jeszcze elementy do zwrotu służy metoda hasMoreTokens().

Page 33: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

33

Rozbiór tekstów - StringTokenizer● Metoda hasMoreTokens() zwraca true, jeśli w łańcuchu znakowym są

jeszcze nie "wyłuskane" elementy i false w przeciwnym razie. Inaczej mówiąc: hasMoreTokens() zwraca true, jeśli następne odwołanie do nextToken() zwróci kolejny element i zwraca false, gdy ew. następne odwołanie do nextToken() spowoduje wyjątek NoSuchElementException.

● Pętla, w której pobieramy kolejne elementy:while (st.hasMoreTokens()) { String s = st.nextToken(); // ... tu coś robimy z s}

● Inna postać konstruktora klasy StringTokenizer pozwala na określenie zbioru separatorów, które będą służyć do wyróżniania elementów. Jeżeli napiszemy np.StringTokenizer st = new StringTokenizer(s, "., ");//to separatorami będą kropka, przecinek i spacja.

● Inną klasą do analizy tekstów jest klasa StreamTokenizer, dostarcza ona nieco bardziej zaawansowanych sposobów rozbioru tekstów, ale wymaga operowania na strumieniach.

Page 34: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

34

Rozbiór tekstów : metoda split● Bardzo elastyczne możliwości analizy tekstów dają wyra enia regularne.ż● W dokumentacji StringTokenizer, do rozbioru tekstów zalecana jest

metoda split z klasy String:public String[] split(String regex)

● Wywołanie txt.split(sep)zwraca tablicę symboli z tekstu txt rozdzielonych separatorami pasującymi do wzorca podanego przez napis- wyrażenie regularne sep.

● Przykład 1:String[] result = "this is a test".split("\\s");

for (int i=0; i<result.length; i++) System.out.println(result[i]); run: this is a test

Page 35: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

35

Rozbiór tekstów : metoda split● Przykład 2:(separator pojedyncza spacja, w tekście 2 spacje)

String[] s = "Ala ma kota".split(" "); System.out.println(s.length);

for (int i=0; i<s.length; i++) System.out.println("*"+s[i]+"*"); run:4*Ala****ma**kota*

● Przykład 3:(separator jedna lub więcej spacji, w tekście 2 spacje)

String[] s = "Ala ma kota ".split(" +");//" +"jedna lub więcej spacji System.out.println(s.length);

for (int i=0; i<s.length; i++) System.out.println("*"+s[i]+"*"); run:3*Ala**ma*

*kota*

Page 36: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

36

Rozbiór tekstów : metoda split● Przykład 4:(w tekście 2 spacje i spacja z przodu, sep: >=1 spacji)

String[] s = " Ala ma kota ".split(" +");//1 lub więcej spacjiSystem.out.println(s.length);

for (int i=0; i<s.length; i++) System.out.println(s[i]); run:4

AlamakotaTablica zawiera cztery elementy z których pierwszy jest pustym napisem, gdyż elementy tablicy zwracanej przez metodę split są podnapisami z których każdy jest zakończony podnapisem pasującym do wyrażenia regularnego lub końcem wiersza.

● Przykład 5 (to samo przy pomocy klasy StringTokenizer) String s = " Ala ma kota "; int i = 0; StringTokenizer st = new StringTokenizer(s); while (st.hasMoreTokens()) { String el = st.nextToken(); System.out.println(el); i++; } System.out.println(i);run:Alamakota3

Page 37: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

37

Scanner – wyrażenia regularne

Kolejną klasą służącą do analizy tekstów jest klasa Scanner. Często korzysta ona z wyrażeń regularnych, np.

● zestaw separatorów, na których skaner rozkłada teksty metodą next()jest wyrażeniem regularnym. Domyślnie jest to wyrażenie określające białe znaki, ale możemy go zmienić metodą useDelimiter(String regex) lub useDelimiter(Pattern p). Metoda reset() przywraca domyślny wzorzec separatorów. Co więcej separatory można zmieniać w trakcie skanowania

● metody next(String regex)i next(Pattern p) zwracają kolejny symbol ograniczony separatorami oraz pasujący do wzorca podanego w wyrażeniu i ustawiają pozycje skanera zaraz za nim lub gdy kolejny symbol nie pasuje do wzorca zwracany jest wyjątek NoSuchElementException. Odpowiednie metody hasNext(wyr_regularne) pozwalają stwierdzić, czy symbol jest dostępny.

● Niejako odwrotnością metod next(…) są metody skip(…), które pomijają separatory i kolejny symbol pasujący do wzorca i ustawiają pozycję skanera za nim, lub przy braku dopasowania zwracany jest wyjątek NoSuchElementException.

● Metody findInLine(wyr_reg) i findWithinHorizon(wyr_reg) wyszukuja w tekście i zwracają napis pasujący do wzorca ignorując separatory.

● można używać wyrażeń przy pobieraniu liczb nextInt(), nextDouble()(przy pobieraniu liczb rzeczywistych skaner uwzględnia lokalizację)

Użycie wyrażeń regularnych w klasie Scanner jest – podobnie jak w klasie String – oparte na odwołaniach do klas Pattern i Matcher, ale jest to wykorzystanie efektywne, bo stosowane wzorce są kompilowane jednokrotnie i przechowywane do ponownego użycia.

Page 38: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

38

Wyrażenia regularne

Wyrażenie regularne stanowi opis wspólnych cech (składni) zbioru łańcuchów znakowych.Możemy sobie wyobrażać, że wyrażenie regularne jest pewnym wzorcem, który opisuje jeden lub wiele napisów, pasujących do tego wzorca. Wzorzec taki zapisujemy za pomocą specjalnej składni wyrażeń regularnych.

Najprostszym wzorcem jest po prostu sekwencja znaków, które nie mają specjalnego znaczenia (sekwencja literałów).

Np. wyrażenie regularne abc stanowi wzorzec opisujący trzy występujące po sobie znaki: a, b i c. Wzorzec ten opisuje jeden napis "abc".

We wzorcach możemy stosować znaki specjalne (tzw. metaznaki) oraz tworzone za ich pomocą konstrukcje składniowe. Do znaków specjalnych należą:

$ ^ . * + ? [ ] ( ) { } \

Uwagi: ● jeśli chcemy traktować znaki specjalne jako literały - poprzedzamy je odwrotnym

ukośnikiem \.● w niektórych konstrukcjach składniowych metaznaki tracą specjalne znaczenie i są

traktowane literalnie.

Page 39: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

39

Wyrażenia regularne- podstawy

Za pomocą znaków specjalnych i tworzonych za ich pomocą bardziej rozbudowanych konstrukcji składniowych opisujemy m.in.

● wystąpienie jednego z wielu znaków - odpowiednie konstrukcje składniowe noszą nazwę klasy znaków (np. litery lub cyfry) : prosta klasa znaków stanowi ciąg znaków ujętych w [] np.[123abc] określa dowolny ze znaków 1,2,3,a,b,c

● zakres znaków (zapisywany z użyciem -), np. [0-9]- dowolna cyfra, [a-zA-Z] - dowolna mała i duża litera alfabetu angielskiego, [a-zA-Z0-9] - dowolna cyfra lub litera

● negacja klasy znaków jeśli pierwszym znakiem jest ^to dopasowanie nastąpi da każdego znaku oprócz wymienionych, np. do wzorca [^abc] będzie pasował każdy znak oprócz a,b,c

● klasy predefiniowane: ➢ . Dowolny znak (w zależności od opcji kompilacji wzorca może pasować lub nie do

znaku końca wiersza)➢ \d Cyfra: [0-9], \D Nie-cyfra: [^0-9]➢ \s "Biały" znak: [ \t\n\x0B\f\r], \S Każdy znak, oprócz "białego": [^\s]➢ \w Jeden ze znaków: [a-zA-Z0-9], znak "dopuszczalny w słowie",

\W Znak nie będący literą lub cyfrą [^\w]➢ \p{Punct} Znak interpunkcji: [! "#$%&'()*+,-./:;<=>?@[\]^_`{|}~]➢ \p{L} Dowolna litera (Unicode)

Ogólna reguła - klasy wprowadzane przez duże litery stanowią negację klas definiowanych przez małe litery.Przykład: wzorzec który dopasowuje teksty składające się z trzech dowolnych cyfr, następujących po nich trzech dowolnych znaków i dwóch znaków, nie będących cyframi: "\d\d\d...\D\D

Page 40: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

40

Wyrażenia regularne- podstawy

● logiczne kombinacje wyrażeń regularnych, np. a+|b – jedno lub więcej wystąpień znaku a lub znak b;

● powtórzenia – w składni wyrażeń regularnych opisywane przez kwantyfikatory, np. kwantyfikator * oznacza wystąpienie 0 lub więcej razy, a kwantyfikator + wystąpienie co najmniej raz:

• jeśli kwantyfikator następuje po literale, wymagane jest wystąpienie tego literału (liczba wystąpień zależy od kwantyfikatora, w szczególności może być 0), np. "12a+" oznacza 1, potem 2, następnie wystąpienie znaku 'a' jeden lub więcej razy (uwaga:"12a+" nie oznacza wystąpienia ciągu znaków 12a jeden lub więcej razy

• gdy kwantyfikator występuje po klasie znaków – dotyczy dowolnego znaku z tej klasy,np. [abc]+ oznacza wystąpienie jeden lub więcej razy znaku a lub b, lub c

• jeśli kwantyfikator ma dotyczyć dowolnego wyrażenia regularnego X, należy zastosować konstrukcję składniową (X)symbol_kwantyfikatora albo (?:X)symbol_kwantyfikatora.

● Przykład. Wyrażenie regularne a.*z (a, kropka, gwiazdka, z) opisuje dowolną sekwencję znaków, zaczynających się od litery a i kończących się literą z. Do wzorca tego pasują np. następujące napisy: "az", "abz", "a x y z".

● Przykład: (?:12a)+ – jedno lub więcej wystąpień napisu „12a”.

Page 41: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

41

Wyrażenia regularne- podstawy

Wyrażeń regularnych możemy użyć m.in. do: ● stwierdzenia czy dany napis pasuje do podanego przez wyrażenie wzorca,● stwierdzenia czy dany napis zawiera podłańcuch znakowy pasujący do

podanego wzorca i ew. uzyskania tego podnapisu i/lub jego pozycji w napisie,

● zamiany części napisu, pasujących do wzorca na inne napisy,● wyróżniania części napisu, które są rozdzielane ciągami znaków pasującymi

do podanego wzorca.

W Javie służą do tego klasy pakietu java.util.regex: Pattern i Matcher.

Przed zastosowaniem wyrażenia regularnego do składniowej analizy jakiegoś napisu musi ono być skompilowane. Obiekty klasy Pattern reprezentują skompilowane wyrażenia regularne, a obiekty te uzyskujemy za pomocą statycznych metod klasy Pattern - compile(...), mających za argument wyrażenie regularne.

Obiekty klasy Matcher wykonują operacje wyszukiwania w tekście za pomocą interpretacji skompilowanego wyrażenia regularnego i dopasowywania go do tekstu lub jego części

Page 42: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

42

Wyrażenia regularne- podstawy

Obiekt-matcher jest zawsze związany z danym wzorcem. Zatem uzyskujemy go od obiektu-wzorca za pomocą metody matcher(...) klasy Pattern, podając jako jej argument przeszukiwany tekst.

Następnie możemy dokonywać różnych operacji przeszukiwania i zastępowania tekstu poprzez użycie różnych metod klasy Matcher.

W szczególności:

● metoda matches() stara się dopasować do wzorca cały podany łańcuch znakowy,

● metoda find() przeszukuje wejściowy łańcuch znakowy i wyszukuje kolejne pasujące do wzorca jego podłańcuchy.

Wszystkie metody dopasowania/wyszukiwania zwracają wartości typu boolean, stwierdzające dopasowanie (true) lub jego brak (false). Więcej informacji o dopasowaniu (jaki konkretnie tekst pasuje do wzorca, gdzie jest jego początek, a gdzie koniec itp.) można uzyskać odpytując matcher o aktualny jego stan za pomocą odpowiednich metod.

Page 43: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

43

Wyrażenia regularne- podstawy

Typową sekwencję operacji, potrzebnych do zastosowania wyrażeń regularnych można opisać w następujący schematyczny sposób.

//wymagany import java.util.regex.*

A) Tekst, podlegający dopasowaniu może być reprezentowany przez obiekt dowolnej klasy implementującej interfejs CharSequence (np. String, StringBuffer, CharBuffer z pakietu java.nio) np:

String text = "196570";

B) Tworzymy wyrażenie regularne jako napis np.

String regexp = "[0-9]+";

C) Kompilujemy wyrażenie regularne i uzyskujemy skompilowany wzorzec.

Pattern pattern = Pattern.compile(regexp);

D) Tworzymy obiekt-matcher związany z danym wyrażeniem, podając przy tym tekst do dopasowania:

Matcher matcher = pattern.matcher(text);

E) Szukamy dopasowania tekstu ( w tekście ) zgodnie ze wzorcem np.

boolean hasMatch = matcher.find();

albo:

boolean isMatching = matcher.matches();

Page 44: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

44

Wyrażenia regularne- podstawy

System.out.println("Tekst: "+ text +"\n"+ (isMatching ?" ":"NIE ")+ " pasuje do wzorca:" +regexp);

//nowy tekst wejściowy

String text2 = "123 127";

//reset matchera

matcher.reset(text2);

isMatching = matcher.matches();

System.out.println("Tekst: "+ text2 +"\n"+ (isMatching ?" ":"NIE ")+ " pasuje do wzorca:" +regexp);

run:

Tekst: 196570

pasuje do wzorca:[0-9]+

Tekst: 123 127

NIE pasuje do wzorca:[0-9]+

Page 45: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

45

Wyrażenia regularne- podstawy

Zdefiniujmy metodę, która jako argumenty otrzymuje wyrażenie regularne oraz analizowany za jego pomocą tekst, a zwraca opis wyników działania metod matches() i find().

String report(String regex, String text) {

String result = "Wzorzec: \"" + regex + "\"\n" +

"Tekst: \"" + text + "\"";

// Kompilacja wzorca

// Gdy wzorzec jest składniowo błędny

// wystąpi wyjątek PatternSyntaxException

Pattern pattern = null;

try {

pattern = Pattern.compile(regex);

} catch (Exception exc) {

return result + "\n" + exc.getMessage();

// zwracamy komunikat o błędzie

}

Page 46: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

46

Wyrażenia regularne- podstawy

// Uzyskanie matchera dla podanego tekstu

Matcher matcher = pattern.matcher(text);

// Próba dopasowania całego tekstu do wzorca

boolean isMatching = matcher.matches();

result += "\nmatches(): Cały tekst" + (isMatching ? "" : " NIE") +

" pasuje do wzorca.";

// Przywrócenie początkowej pozycji matchera

matcher.reset();

// Teraz stosujemy metodę find() // Jej wywołanie zwraca true po znalezieniu pierwszego // pasującego do wzorca podłańcucha w tekście // Kolejne wywołania pozwalają wyszukiwać kolejne // pasujące podłańcuchy.

Page 47: Programowanie w środowisku graficznym- wykład 4int num1 = Integer.parseInt(snum1); //operacje na num1} catch (NumberFormatException exc) {//obsługa wyjątku } 7 WYJĄTKI -przykład

47

Wyrażenia regularne- podstawy// Wynik false oznacza, że w tekście nie ma już// pasujących podłańcuchów boolean found = matcher.find();

if (!found)

result += "\nfind():Nie znaleziono żadnego podłańcucha " +"pasującego do wzorca";

else

do {

result += "\nfind(): Dopasowano podłańcuch \"" + matcher.group() +

"\" od pozycji " + matcher.start() +

" do pozycji " + matcher.end() + ".";

} while(matcher.find());

return result;

}