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/ – $veta =~ /MeDved/ – $veta =~ /medvedi/
true false 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/ • ”Abeceda neni veda, a to ani pro medveda.“
– $veta =~ /a/ • ”Abeceda neni veda, a to ani pro medveda.“
– $veta =~ / a/ • ”Abeceda neni veda, a to ani pro medveda.“
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/ • ”Abeceda neni veda, a to ani pro medveda.“
– $veta =~ /[^lcv]eda/
false
• ”Abeceda neni veda, a to ani pro medveda.“
9
Žolík • . reprezentuje libovolný znak – neplést s ? nebo * - to je něco jiného!!!
• příklad – $veta =~ /n.n/ • ”Abeceda neni veda, a to ani pro medveda.“
– $veta =~ / .... / • ”Abeceda neni veda, a to ani pro medveda.“
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
• ”Abeceda neni veda, a to ani pro medveda.“
– $veta =~ /pro$/
false
• ”Abeceda neni veda, a to ani pro medveda.“
– $veta =~ /\b[cv]eda\b/ true • ”Abeceda neni veda, a to ani pro medveda.“ 11
Opakování • u každého elementu výrazu můžeme specifikovat počet opakování – – – – – –
• \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 =~ /./ • ”Abeceda neni veda, a to ani pro medveda.“
– $veta =~ /\./ • ”Abeceda neni veda, a to ani pro medveda.“
– $veta =~ /\sveda\b/
# \b není součástí nalezeného výrazu
• ”Abeceda neni veda, a to ani pro medveda.“
– $veta =~ /veda./ • ”Abeceda neni veda, a to ani pro medveda.“ – $veta =~ /veda\./ • ”Abeceda neni veda, a to ani pro medveda.“
17
Skupiny • zápis pomocí () – 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>/;
– 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
• 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í ;))