Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Copyright © 2008, Rudolf Pecinovský 1 Regulární výrazy Rudolf Pecinovský.

Podobné prezentace


Prezentace na téma: "Copyright © 2008, Rudolf Pecinovský 1 Regulární výrazy Rudolf Pecinovský."— Transkript prezentace:

1 Copyright © 2008, Rudolf Pecinovský 1 Regulární výrazy Rudolf Pecinovský

2 Motto Once a programmer had a problem. He thought he could solve it with a regular expression. Now he had two problems. 2 Copyright © 2008, Rudolf Pecinovský

3 3 Co to je  Nejsou regulérní, ale opravdu regulární  Zavedené ve verzi 1.4  Regulární výraz = řetězec popisující vzor (předpis), podle nějž se:  Rozhoduje o správné podobě zadaného řetězce  V zadaném řetězci se vyhledává řetězec popsaný vzorem  V zadaném řetězci se nahrazují výskyty řetězce popsaného jedním vzorem řetězcem popsaným jiným vzorem  Příklady využití  Validaci vstupů, kontroly formátu dat  Dělení řetězce na části podle složitějších kritérií

4 4 Copyright © 2008, Rudolf Pecinovský Kde jsou jejich třídy a jak se používají  Definovány v balíčku java.util.regex  Třída Pattern – vnitřní reprezentace programu definovaného daným regulárním výrazem  Třída Matcher – interpret dodaného programu nad zadaným výrazem  Třída PatternSyntaxException – výjimka popisující vzniklý problém  Postup použití 1. Přeloží se „program“ a vytvoří se vzor 2. K danému programu se vytvoří prohlížeč zadaného textu 3. Prohlížeč pak žádáme o různé informace Pattern p = Pattern.compile("a*b"); Matcher m = p.matcher("aaaaab"); boolean b = m.matches();

5 Copyright © 2008, Rudolf Pecinovský 5 Metody pro validaci a vyhledávání

6 6 Copyright © 2008, Rudolf Pecinovský Metody třídy Pattern  static Pattern compile(String regex) static Pattern compile(String re, int flg)  Přeloží zadaný text a vytvoří nový vzor při respektování případných zadaných příznaků  static String quote(String s)  Vrátí text, jehož překladem vznikne vzor, kterému bude zadaný text vyhovovat

7 7 Copyright © 2008, Rudolf Pecinovský Příznaky ovlivňující překlad CANON_EQ Písmeno následované akcentem považuje za znak s daným akcentem CASE_INSENSITIVE – Nedbá na velikost písmen COMMENTS Ignoruje mezery a povoluje komentáře začínající znakem # DOTALL V tomto režimu zastupuje znak. (tečka) také konce řádků (jinak ne) LITERAL Metaznaky považuje za normální znaky MULTILINE Umožňuje vyhledávat konce řádků UNICODE_CASE Ignorace velikosti znaků odpovídá standardu Unicode UNIX_LINES Za konec řádku je považován pouze \n

8 8 Copyright © 2008, Rudolf Pecinovský Metody instancí třídy Pattern  Matcher matcher(CharSequence input)  Vytvoří vyhledávač vzoru v zadaném textu  String[] split(CharSequence input) String[] split(CharSequence inp, int limit)  Vrátí vektor řetězců oddělených v zadaném textu daným vzorem s respektováním pořadí. Neobsahuje-li text vzor, je vrácen celý.  Parametr limit specifikuje maximální povolenou velikost pole, je-li nekladný, není počet vracených řetězců omezen  String pattern() String toString()  Vrátí text, jehož překladem vznikl daný vzor  int flags()  Vrátí číslo, z nějž lze odvodit nastavené příznaky

9 9 Copyright © 2008, Rudolf Pecinovský Metody pro porovnávání a vyhledávání  boolean matches()  Zjistí, jestli (celý) text v oblasti odpovídá vzoru  boolean lookingAt()  Zjistí, jestli se v textu nachází pasáž odpovídající vzoru; hledá vždy od začátku oblasti  boolean find() boolean find(int start)  Pokusí se najít další pasáž odpovídající vzoru

10 10 Copyright © 2008, Rudolf Pecinovský Informace o výsledku1/2  int groupCount()  Vrátí počet nalezených výskytů vzoru v textu  String group() String group(int group)  Vrátí další, resp. zadanou skupinu odpovídající vzoru  int start() int start(int group)  Vrátí index prvního znaku nalezené/zadané skupiny  int end() int end(int group)  Vrátí index za posledním znakem nalezené/zadané skupiny

11 11 Copyright © 2008, Rudolf Pecinovský Informace o výsledku2/2  MatchResult toMatchResult()  Vrátí přepravku s informacemi o výsledcích porovnávání  MatchResult – rozhraní s metodami z předchozí stránky  boolean hitEnd()  Oznámí, zda bylo při posledním hledání dosaženo konce vstupu  boolean requireEnd()  Oznámí, zda by další vstupující text ovlivnil úspěšnost nalezení textu odpovídajícího vzoru

12 12 Copyright © 2008, Rudolf Pecinovský Ovlivnění chodu vyhledávače  Matcher reset() Matcher reset(CharSequence input)  Resetuje vyhledávač a nastaví jej na nový text  Matcher usePattern(Pattern newPattern)  Změní vzor, který bude v textu vyhledáván, nemění se však aktuální pozice v prohledávaném textu  Matcher region(int start, int end)  Nastaví nové meze prohledávané oblasti v textu

13 Copyright © 2008, Rudolf Pecinovský 13 Syntaxe vzorů

14 14 Copyright © 2008, Rudolf Pecinovský Syntaxe: Jednotlivé znaky  S výjimkou znaků speciálního určení vystupuje každý znak sám za sebe  Platí i escape-sekvence Javy: \\ \uhhhh \t \n \r \f \a  Pro znak Escape (\u001B) lze použít \e  Řídící znaky typu Ctrl+X je možno zadávat ve tvaru \cX  Znak s kódem do 127 lze zadat také pomocí pouhých dvou číslic: \xhh  V osmičkové soustavě lze znaky zadat jednou až třemi číslicemi: \0o \0oo \0ooo

15 15 Copyright © 2008, Rudolf Pecinovský Příklady  Text: Okolo "Hradce" v male zahradce  Vzor: ad 1 - [ 9..11]: «ad» 2 - [26..28]: «ad»  Vzor: \x [ 5.. 6]: « » 2 - [12..13]: « » 3 - [14..15]: « » 4 - [19..20]: « »  Vzor: \u0020\x [ 5.. 7]: « "»

16 16 Copyright © 2008, Rudolf Pecinovský Syntaxe: Množiny znaků [abc] Jeden ze znaků uvnitř závorek (zde a či b či c ) [^abc] Žádný ze znaků uvnitř závorek [a-zA-Z] Rozsah znaků (znaky a až z a znaky A až Z včetně) [a-d[m-p]] Sjednocení Znaky a až d nebo znaky m až p [a-z&&[^qw]] Průnik: znaky a až z s výjimkou znaků q a w [a-z&&[^m-p]] Průnik: znaky a až z s výjimkou znaků m až p

17 17 Copyright © 2008, Rudolf Pecinovský Příklady1/2  Text : Okolo Hradce v male zahradce  Vzor: o[^o] 1 - [ 2.. 4]: «ol» 2 - [ 4.. 6]: «o »  Vzor: [A-Z] 1 - [ 0.. 1]: «O» 2 - [ 6.. 7]: «H»  Vzor: [ ][^A-Z][a-z] 1 - [14..17]: « ma» 2 - [19..22]: « za»

18 18 Copyright © 2008, Rudolf Pecinovský Příklady2/2  Text : Příliš žluťoučký kůň úpěl ďábelské ódy  Vzor: [^\x00-\xff] – znaky s diakritikou, které nejsou v západoevropské znakové sadě 1 - [ 1.. 2]: «ř» 2 - [ 5.. 6]: «š» 3 - [ 7.. 8]: «ž» 4 - [10..11]: «ť» 5 - [13..14]: «č» 6 - [18..19]: «ů» 7 - [19..20]: «ň» 8 - [23..24]: «ě» 9 - [26..27]: «ď»

19 19 Copyright © 2008, Rudolf Pecinovský Syntaxe: Skupinové znaky. (tečka) Libovolný znak \d Číslice, tj. [0-9] \D NEčíslice, tj. [^0-9] \s Bílý znaky, tj. mezera, tabulátor, konec řádku, konec stránky \S NE bílý znak \w Znak [A-Za-Z0-9_] \W Znak [^\w]

20 20 Copyright © 2008, Rudolf Pecinovský Příklady  Text: Okolo "Hradce" v male zahradce  Vzor: \S\s\S 1 - [ 4.. 7]: «o "» 2 - [13..16]: «" v» 3 - [20..23]: «e z»  Vzor: \w\W\W\w 1 - [ 4.. 8]: «o "H» 2 - [12..16]: «e" v»  Vzor:..\s [ 3.. 8]: «lo "H» 2 - [12..17]: «e" v » 3 - [19..24]: «le za»

21 21 Copyright © 2008, Rudolf Pecinovský Syntaxe: Kvantifikátory (počet opakování) ?0 nebo 1 výskyt předchozího znaku +1 a více výskytů předchozího znaku * Libovolný počet výskytů předchozího znaku (včetně 0) { n } Přesně n opakování předchozího znaku { n,} Minimálně n opakování předchozího znaku { m, n } Minimálně m a maximálně n opakování předchozího znaku

22 22 Copyright © 2008, Rudolf Pecinovský Příklady1/4  Text: Příliš žluťoučký kůň úpěl ďábelské ódy  Vzor: [\x00-\x7F&&[^ ]]{2,} výsledek je tomto případě ekvivalentní aplikaci vzoru \w{2,} 1 - [ 3.. 5]: «li» 2 - [ 8..10]: «lu» 3 - [11..13]: «ou» 4 - [28..33]: «belsk» 5 - [36..38]: «dy»  Vzor: \s\S+\s 1 - [ 6..17]: « žluťoučký » 2 - [20..26]: « úpěl »

23 23 Copyright © 2008, Rudolf Pecinovský Příklady2/4  Zadání: Definujte regulární výraz umožňující ověřit, že řetězec odpovídá vodáckému pokřiku public static void ahoj() { String[] as = {"ahj", "ahoj", "ahooj", "ahoooj"}; for( String s : as ) { String t = "aho+j"; System.out.println( s + " == " + s.matches( t ) ); }

24 24 Copyright © 2008, Rudolf Pecinovský Příklady3/4  Zadání: Napište regulární výraz, pomocí kterého je možno zjistit, zda lze v Javě daný řetězec považovat za identifikátor public static void identifikátor() { String[] as = { "12a", "_123", "$a7", "_$_" }; String rv = "[\\$\\w&&\\D][\\w\\$]*"; for( String s : as ) { System.out.println( s + " == " + s.matches( rv ) ); }

25 25 Copyright © 2008, Rudolf Pecinovský Příklady4/4  Zadání: Rozdělte text na slova public static void slova() { String[] as = { "a b c d", "a b c de" }; String rv = "\\s+"; for( String s : as ) { String[] ss = s.split( rv ); System.out.print( s + " == " ); for( String w : ss ) System.out.print( w + "*" ); System.out.println(); }

26 26 Copyright © 2008, Rudolf Pecinovský Syntaxe: Hranice ^ Začátek řádku $ Konec řádku \b Hranice slova \B Není hranice slova \Q Začátek citace \E Konec citace \A Začátek vstupu \z Konec vstupu \Z Konec vstupu bez ukončovacího znaku \G Konec předchozí nalezené skupiny

27 27 Copyright © 2008, Rudolf Pecinovský Příklady  Text: Okolo Hradce v malé zahrádce  Vzor: \b\w+\b 1 - [ 0.. 5]: «Okolo» 2 - [ 6..12]: «Hradce» 3 - [13..14]: «v»  Vzor: \b.a\S* 1 - [15..19]: «malé» 2 - [20..28]: «zahrádce»  Vzor:...[eé]\b 1 - [ 8..12]: «adce» 2 - [15..19]: «malé» 3 - [24..28]: «ádce»

28 28 Copyright © 2008, Rudolf Pecinovský Syntaxe: Další operátory XYZnaky X a Y musí být vedle sebe, X|YBuď znak X nebo znak Y, (X)Označení skupiny, \n Obsah n-té skupiny  Při nahrazování se na danou skupinu odvolává výrazem $n

29 29 Copyright © 2008, Rudolf Pecinovský Práce se skupinami  Skupiny je možno vnořovat  Pořadí skupiny se počítá podle její otevírací závorky  ((A)(B(C)))(D) 1. ((A)(B(C))) 2. (A) 3. (B(C)) 4. (C) 5. (D)

30 30 Copyright © 2008, Rudolf Pecinovský Příklady1/3  Text: Okolo Hradce v male zahradce  Vzor: (a|e|o).*\1 1 - [ 2.. 5]: «olo» 2 - [ 8..22]: «adce v male zahra»  Vzor: (...).*\1 1 - [ 7..26]: «radce v male zahrad»

31 31 Copyright © 2008, Rudolf Pecinovský Příklady2/3  Vzor pro vyhledání reálného čísla ve fixním tvaru: [+|-]?((\d+(\.\d*)?)|(\.\d+)) ([Ee][+-]\d{1,3})?  Text: číslo 123 nebo 1.2 nebo.2 nebo 1.3e [ 6.. 9]: «123» 2 - [15..18]: «1.2» 3 - [24..26]: «.2» 4 - [32..38]: «1.3e23»

32 32 Copyright © 2008, Rudolf Pecinovský Příklady3/3  Vzor pro oddělovač: (\s+)|((\.|,)\s*)(\b|$)  Text: Jdi domů,nakup a sbal si. Pak přijď. 0: «Jdi» 1: «domů» 2: «nakup» 3: «a» 4: «sbal» 5: «si» 6: «Pak» 7: «přijď»

33 33 Copyright © 2008, Rudolf Pecinovský Syntaxe: Agresivita kvantifikátorů  Agresivitu („hladovost“) kvantifikátorů můžeme ovlivnit příponou – rozlišujeme kvantifikátory:  Zdráhavé (reluctant): ?? *? +? {}?  Zaberou minimální počet znaků doporučených vzorem  Hladové (greedy): ? * + {}  Zaberou maximální počet znaků doporučených vzorem, ale pokud by porovnání následujících částí vzoru nevycházelo, vrátí část zabraných znaků, aby bylo možno zkusit vše znovu  Lakomé (possessive): ?+ *+ ++ {}+  Zaberou maximální počet znaků doporučených vzorem a nezávisle na úspěšnosti porovnání následujících částí vzoru

34 34 Copyright © 2008, Rudolf Pecinovský Příklady  Text: Okolo Hradce v male zahradce  Zdráhavý vzor: (a|e|o).*?\1 1 - [ 2.. 5]: «olo» 2 - [ 8..17]: «adce v ma» 3 - [18..28]: «e zahradce»  Hladový vzor: (a|e|o).*\1 1 - [ 2.. 5]: «olo» 2 - [ 8..22]: «adce v male zahra»  Lakomý vzor: (a|e|o).*+\1 Nic nenalezeno

35 Copyright © 2008, Rudolf Pecinovský 35 Nahrazování

36 36 Copyright © 2008, Rudolf Pecinovský Metody pro nahrazování textu  String replaceFirst(String replacement) String replaceAll(String replacement)  Nahradí první/všechny výskyt(y) vzoru zadaným řetězcem  Matcher appendReplacement( StringBuffer sb, String replacement)  Přidá na konec zadaného StringBuffer u text projitý při posledním hledání přičemž nalezený výraz na konci nahradí  StringBuffer appendTail(StringBuffer sb)  Přidá na konec zadaného StringBuffer u doposud neprojitý text, tj. text za posledním nalezeným výskytem vzoru  boolean requireEnd()  Oznámí, zda by další vstupující text ovlivnil úspěšnost nalezení textu odpovídajícího vzoru

37 37 Copyright © 2008, Rudolf Pecinovský Příklad1/2  V regulárním výrazu zapsaném ve zdrojovém textu musí být všechna zpětná lomítka zdvojená  Zadání: Napište regulární výraz, pomocí kterého je možno najít odstranit všechny zdvojené mezery v zadaném textu public static void mezery() { String[] as = { "a b c d", "a b c de" }; String rv = "\\s{2,}"; for( String s : as ) { System.out.println( s + " == " + s.replaceAll( rv, "_" ) ); }

38 38 Copyright © 2008, Rudolf Pecinovský Příklad2/2 public class TestujICPU implements ITest { public static void test() { Pattern p = Pattern.compile("cat"); Matcher m = p.matcher ("one cat two cats in the yard"); StringBuffer sb = new StringBuffer(); while (m.find()) { m.appendReplacement(sb, "dog"); } m.appendTail(sb); System.out.println(sb.toString()); } //Tiskne: one dog two dogs in the yard

39 Copyright © 2008, Rudolf Pecinovský 39 Děkuji za pozornost Rudolf Pecinovský mail: ICQ:

40 40 Copyright © 2008, Rudolf Pecinovský ===== KONEC =====

41 41 Copyright © 2008, Rudolf Pecinovský Snímek  Bod  Podbod

42 Copyright © 2008, Rudolf Pecinovský 42 Nadpis kapitoly

43 43 Copyright © 2008, Rudolf Pecinovský —L0x-y: Kapitola o Pgm  Vzor Pgm

44 44 Copyright © 2008, Rudolf Pecinovský — Snímek Pgm  Vzor Pgm

45 45 Copyright © 2008, Rudolf Pecinovský Program1/4 public class TestujICPU implements ITest { public static void main( String[] args ) { TestujICPU t = new TestujICPU(); KolektorTříd.prověř( ICPU.class, t ); } public void testuj( ICPU instance ) { cpu = instance; čísloVerze = cpu.getVerze(); verze = new Verze( čísloVerze ); System.out.println("Verze č. "+čísloVerze); testPřítomnostiOperací(); testProváděníOperací(); } //...


Stáhnout ppt "Copyright © 2008, Rudolf Pecinovský 1 Regulární výrazy Rudolf Pecinovský."

Podobné prezentace


Reklamy Google