Regexy ====== Regexové literály a operátory ----------------------------- /regex/ <-- regexový literál (instance třídy Regex) rx|regex| <-- to samé s libovolnými oddělovači rx{{regex}} <-- včetně párových a zdvojených (jako quoting oper.), kromě kulatých závorek (pletlo by se s voláním fce) $s ~~ /regex/ <-- testuje, zda string vyhovuje regexu (pokud ano, vrací Match objekt, který je true, jinak Nil) m/regex/, m{regex} <-- zkratka za $_ ~~ /regex/ (lib. oddělovač) $s ~~ m/regex/ <-- chová se jako $s ~~ rx/regex/ (výjimka) @pole.grep(/regex/) <-\ when /regex/ {...} + typické použití ve smartmatchujících konstrukcích sub f($x where /regex/) <-/ rx:i/abc/, m:i/abc/ <-- modifikace příslovci (:i = ignore case, další níže) /:i abc/ <-- alternativní zápis téhož $s ~~ s/regex/repl/ <-- nahrazení prvního výskytu regexu POZOR, nahrazení je in-place: * levá strana musí být R/W kontejner * vrací match objekt, nikoli výsledek nahrazení $s ~~ s:g/regex/repl/ <-- nahrazení všech výskytů (:g je příslovce) s/regex/repl/ <-- zkratka za $_ ~~ s/regex/repl/ s!regex!repl! <-- alternativní oddělovače (nepárové) s[regex] = "repl" <-- s párovými oddělovači se používá přiřazovací syntaxe (s{regex}{repl} je nelegální), ekvivalentní s/regex/repl/, ale napravo může být jakýkoli perlový výraz; ve skutečnosti ekvivalentní s/regex/{"repl"}/ S/regex/repl/ <-- (velké S) nahradí první výskyt regexu v kopii $_, vrátí výsledek (nemění $_) S/regex/repl/ given $s <-- idiom: nahrazení v kopii nějakého stringu Syntaxe regexů -------------- - mezery a newliny se ignorují - mohou obsahovat #komentáře ## Výrazy matchující jeden znak ## . <-- libovolný znak (včetně newline) x <-- písmena, čísla (unicodové kat. L, N) a podtržítko matchují sebe sama vše ostatní třeba escapovat \: <-- backslashovaný speciální znak (kromě písmen a číslic) matchuje sebe sama \n <-- newline (logický: LF nebo CRLF) \h <-- libovolná horizontální mezera (např. mezera či tabulátor) \v <-- libovolná vertikální mezera (newline, vertikální tab, formfeed, etc.) \s <-- libovolná mezera (horizontální nebo vertikální) \d <-- číslice (unicode kategorie N) \w <-- libovolný "znak slova" (unicode písmeno, číslice, podtržítko) \N, \S, \H, \V, \D, \W <-- negace předchozích skupin (např. \S matchuje libovolný nemezerový znak) <:Lu> <-- znak s danou unicode vlastností (zde Lu = uppercase písmeno) <:Script> <-- totéž pro stringovou vlastnost (příslovečná syntaxe) <[abc]> <-- znak z dané množiny <[a..z 0..9]> <-- jde používat i rozsahy <:L+:N-[abc]> <-- kombinování množin znaků (lib. písmeno nebo číslice kromě a,b,c) <:L & :Script> <-- průnik množin (lib. písmeno latinky) ## Výrazy matchující substringy ## "nějaký řetěžec" <-- matchuje daný řetězec (běžná P6 syntaxe vč. escapování) $str <-- matchuje doslovně obsah $str (regexové metaznaky v $str nemají speciální význam) @pole <-- matchuje doslovně libovolný z prvků pole (jako [$pole[0] | $pole[1] | ...]) < for while if > <-- jako [for|while|if] (za '<' musí být mezera) ## Kvantifikátory ## * <-- libovolný počet opakování (i 0) + <-- aspoň jedno opakování **5 <-- přesně 5 opakování **3..5 <-- 3 až 5 opakování (včetně) % regex <-- za kvantifikátorem: mezi opakováními je daný oddělovač %% regex <-- ... oddělovač může být i za posledním opakováním [\d+]* % [','\h*] <-- příklad: seznam čísel oddělených čárkami (s volitelnými mezerami za čárkou) 'aaaa' ~~ rx{a+} <-- chová se hladově, matchne všechno 'aaaa' ~~ rx{a+?} <-- chová se střídmě, matchne jen první a 'aaaa' ~~ rx{a+!} <-- zdůrazníme hladovost (totéž co a+) 'aaaab' !~~ /a+: ab/ <-- ':' zakazuje backtrackování ## Další běžné operátory ## abc || def <-- zkusí abc, když to nejde, zkusí def abc | def <-- zvítězí varianta, které vyhovuje víc textu [a|b]+ <-- posloupnost znaků, každý z nich je a nebo b (a|b)+ <-- totéž, ale se zachycením obsahu posloupnosti ^ $ <-- kotvička na začátek / konec řetězce ^^ $$ <-- kotvička na začátek / konec řádku ## Match objekty ## Reprezentuje celý match i jeho části (captures). Návratová hodnota ~~, po úspěšném matchi též aliasován na $/ ~$match <-- matchnutá část stringu $match.from <-- počáteční index matchnuté části (vůči celému stringu, ne nadřazené capture) $match.to <-- koncový index matchnuté části $match.prematch <-- část stringu před matchem $match.postmatch <-- část stringu po matchi ## Zachytávání (capturing) ## [...] <-- non-capturing seskupování (...) <-- zachytávající závorky $=(...) <-- pojmenovaný capture Zachycené závorky jsou k dispozici (v kódu) indexováním Match objektu: $/[0] či $0 <-- první závorka $/{'název'} či $ <-- pojmenovaná závorka (lze používat i na pravé straně substituce) Kvantifikované captures jsou přístupné jako pole. Pro seznam čísel výše bude $0 pole matchnutých čísel. Číslování závorek je stromovité: ( ( ) ( ) ) ( $=( ) )* | |--| |--| | |------| | $0[0] $0[1] | $1[$i] |---------------| |-----------------------| $0 $1[$i] ($i-té opakování) Hodnotou $0 apod. je Match objekt popisující část řetězce matchovanou danou závorkou (lze převést na string). ## Assertions ## << <-- levá hranice slova >> <-- pravá hranice slova <-- look-ahead <-- look-behind <-- negativní look-ahead <-- podmínka na zatím zachycená data ## Subregexy ## my regex number { \d+ } <-- pojmenovaný regex <-- odkaz na pojmenovaný regex (zachytává do $) <&number> <-- nezachytávající verze (uvnitř gramatik <.number>) <-- zachytává pod daným jménem <~~> <-- rekurzivní zavolání aktuálního regexu , ... <-- předdefinovaná pravidla # Pojmenovaný regex je ve skutečnosti subrutina, může mít parametry, # může být multi (ale nedá se užitečně zavolat jinak než z <...> v regexu) my regex number($max) { \d+ } "56" ~~ // ## Příklady ## ( (<[0-9]>+) )**4 % '.' <-- IP adresa # $0 je relativní vůči vnější závorce