Regulární výrazy jemný úvod Miloslav Brada
Regulární výrazy - RegExy K čemu vůbec jsou? Nástin možností Jednoduché vzory, pravidla regexpů Metaznaky Opakování Skupiny Jednoduchý příklad na závěr 2
Co RegExy umožňují odpovědět na otázku obsahuje daný text požadovaný vzor? vyhledávání textu shoda s maskou (email, telefonní číslo) provádět nahrazení nalezeného textu jiným textem zjistit, co vlastně bylo nalezeno někdy vlastně ani pořádně nevíme co hledáme obecně zjednodušit mnoho operací týkajících se hledání, ověřování a manipulace s textem, které by bylo jinak nutné provádět ručně/velice komplikovaně programovat 3
Setkání s RegExy pravděpodobě každý máme již zkušenost masky souborů (*.sh,???.iso, atd...) vyhledávání (*, % v SQL, atd...) v této podobě dosti omezené možnosti, regexy nám nabízejí mnohem víc!!! součástí mnoha nástrojů jazyky Perl, PHP, Java, Python, Javascript, BASH... GNU nástroje sed, awk, [ef]grep, vim... v mnoha dalších Eclipse, OpenOffice... 4
Příklady... 5
Možnosti specifikace vzorů můžeme si zvolit: přesně jaké znaky chceme či naopak nechceme mít na daných pozicích použít žolíky s omezujícími pravidly vyhledávání podle pozice na začátku, na konci na hranici slova, za bílým znakem, před libovolnou číslicí atd... limity na počet opakování, požadavek nutné přítomnosti, volitelné přítomnosti hledaní podle několika možných alternativ hledaní podle toho, co už bylo nalezeno 6
Začínáme... Testovací věta: $veta= Abeceda neni veda, a to ani pro medveda. Vyhodnocení pomocí $veta =~ /REGEXP/ $veta =~ /medved/ true $veta =~ /MeDved/ false $veta =~ /medvedi/ false v RegExech se rozlišují malá/velká písmena prohledávaný text musí odpovídat vzoru celý, nestačí jen část 7
Začínáme... prohledávání se děje zleva doprava první nález ukončuje hledání příklad $veta =~ /veda/ $veta =~ /a/ $veta =~ / a/ 8
Znakové alternativy znakové alternativy se specifikují pomocí [] rozsahy znaků pomocí intervalu, např. [a-z], [0-9] možnost kombinace [0-9a-fA-F] negace pomocí ^, platí pro celý obsah závorky [^0-9abcdef] žádná číslice, žádný ze znaků a, b, c, d, e, f příklad $veta =~ /[cv]eda/ $veta =~ /[^lcv]eda/ false 9
Žolík. reprezentuje libovolný znak neplést s? nebo * - to je něco jiného!!! příklad $veta =~ /n.n/ $veta =~ /... / 10
Určení pozice ^ znamená začátek řetězce neplést s [^a-z], tady ^ znamená negaci $ znamená konec řětězce \b znamená hranice slova příklad $veta =~ /^veda/ false $veta =~ /pro$/ false $veta =~ /\b[cv]eda\b/ true 11
Opakování u každého elementu výrazu můžeme specifikovat počet opakování * 0 -? 0-1 + 1 - {m,n} m - n {n,} n - {n} přesně n regulární výrazy jsou žravé vyhoví nejdelší možný podřetězec odpovídající výrazu 12
Opakování příklady příklad $veta =~ /Abec.*a/ $veta =~ /v?ed/ $veta =~ /v+ed/ $veta =~ /veda{2,}/ false 13
Opakování omezení žravosti připojením? *? 0 -, nejlépe 0?? 0-1, nejlépe 0 +? 1 -, nejlépe 1 {m,n}? m - n, nejlépe m {n,}? n -, nejlépe n snaha o nalezení co nejkratšího řetězce, ještě vyhovujícího výrazu 14
Opakování příklady příklad, $veta= aaaabbbccd ; $veta =~ /b*?/ true!!! aaaabbbccd $veta =~ /b+?/ aaaabbbccd $veta =~ /a{2,}/ aaaabbbccd $veta =~ /a{2,}?/ aaaabbbccd 15
\d, \D číslice, ^číslice - [0-9] \s, \S Metaznaky bílý znak, ^bílý znak - [ \t\r\n\f] \w, \W písmeno, číslíce v úvahu se berou I znaky národní abecedy, tj. není to to samé jako [a-za-z0-9] \ speciální znak, ruší význam znaků ()[]{}$^. *+?\ \ se zapisuje zdvojeně \\ 16
Metaznaky příklady příklad $veta =~ /./ $veta =~ /\./ $veta =~ /\sveda\b/ # \b není součástí nalezeného výrazu $veta =~ /veda./ $veta =~ /veda\./ 17
zápis pomocí () Skupiny definují alternativní podvýrazy dá se na ně zpětně odkazovat $veta =~ /(jo po)hanka/ odpovídá jak johanka tak I pohanka zpětné odkazy se zapisují \1, \2, \3... \1, \2... odpovídá první, druhé... skupině př. na nalezení pěti písmenného palindromu $text =~ /(.)(.).\2\1/ - najde např. kajak 18
Skupiny jako vedlejší efekt vznik proměnných $1, $2... pokud nechceme vznik zpětného odkazu, použijeme skupinu (?:REGEXP) příklady zjištění obsahu buňky v HTML $html =~ /<td>(.*?)<\/td>/; parsování telefonního čísla, (konečně něco aspoň trochu zajímavého) $cislo =~ /(?:\+ 00)\s?(\d{1,3})\s?((\d (?:\s))*)\b/ v $1 bude národní předvolba v $2 cislo 19
Nahrazení a příklad v perlu operací $text =~ s/regexp/nahrada/x; nahradí v textu výraz REGEXP textem v NAHRADA x mohou být další volby, např. ignore case, global zdokonalené parsování čísla $cislo =~ /(?:(?:\+ 00)\s?(\d{1,3})\s?)?(\d{1,3})\s?((\d (?:\s))*)\b/; $zeme=$1; $predvolba=$2; $ucastnik=$3; zbavení se mezer v $ucastnik $ucastnik =~ s/\s//g; příklady vstupů, které náš výraz spravně vyhnodnotí +420234123456, 00420 234 12 34 56, +420 2 341 234 56, +420 234 123 456, 00 420 2 3 4 1 2 3 4 5 6 234 123 456, 234 12 34 56, 234123456 v tomto případě bude $1 nedefinované (správné chování!!!) 20
Shrnutí RegExpy jsou mocný nástroj základem je implementace v Perlu jinde je někdy obrácený význam speciálních znaků a musí se před ně psát \ ostatní nástroje často neumí vše, co Perl man perlretut další zdroje www.regularnivyrazy.info www.regexp.cz tutoriály na abclinuxu.cz, root.cz spousta dalších zdrojů (google napoví ;)) 21
\b[zz]ávěr(?:em)?\.\.\.\b Děkuji za pozornost... 22