ARCHIV |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Software (10844)
Distribuce (131)
Skripty (697)
Menu
Diskuze
Informace
|
Perl (18) - Regulární výrazy - množiny znakůVe 3. pokračování o regulárních výrazech jsou představeny třídy znaků. Množina znaků je skupina obyčejných znaků. Pokud ji uvedeme ve vzoru, potom se taková množina chová jako 1 ze znaků, které obsahuje. Máme několik možností, jak množinu definovat. libovolný znakZačneme tím nejjednodušším. Znak tečka zastupuje 1 libovolný znak mimo konce řádků. Poznámka - Pokud chcete zahrnout do množiny znaků, které tečka zastupuje i znak konce řádku, použijte přepínač /s. Příklad vypisuje slova s názvem o délce 4:
@slova = qw(C++ Perl Python Ruby Java); Poznámka - Nutno ale poznamenat, že místo cyklu foreach bychom mohli jednoduše použít funkci grep:
$, = "\n"; Výčet znakůJe možné specifikovat užší množinu znaků než libovolný znak. K tomu slouží hranaté závorky. Skupina znaků, které jsou v hranatých závorkách, tvoří tuto užší množinu. Znaky nejsou nijak speciálně odděleny, protože to není potřeba.
print "MATCHED" if "SUSE Linux 9.2" =~ /S[Uu]SE Linux 9\.[123]/; 1. a 2. příklad vrací 1, poslední příklad prázdný řetězec. Číslo 4 totiž není v dané množině povolených znaků. Pomocí alternace můžeme vytvořit vzor, kterému vyhoví i "SUSE Linux 10.0".
print "MATCHED" if "SUSE Linux 10.0" =~ /S[Uu]SE Linux (9\.[123]|10\.0)/; Poznámka - Zde návratová hodnota obsahuje zapamatované hodnoty. Pamatování jsme zatím neřešili. Zkusme si spočítat, kolika různým řetězcům náš poslední vzor vyhoví. Aby to nebylo nekonečno, vzor nejdříve ukotvíme:
/^S[Uu]SE Linux (9\.[123]|10\.0)$/
Nyní pojďme znak po znaku (resp. množinu po množině), u každého zjistíme počet možností, a tyto počty mezi sebou vynásobíme. 1. znak, S, je samostatný znak - tedy množina jediného znaku. [Uu] je množina 2 znaků a jsou tedy 2 možnosti. Dále máme až k závorce vždy 1 možnost. Potom následuje 1 z řetězců 9.1, 9.2, 9.3 nebo 10.0. Tedy 4 možnosti. Velikosti množin mezi sebou vynásobíme, a tím získáváme 1*2*1*1*1*1*1*1*1*1*1*4 = 8. Naší šabloně tak vyhoví 8 řetězců. Pro výčet znaků existuje několik usnadnění. Představte si, že chcete definovat množinu, které vyhovuje libovolné anglické písmeno. Řešení může vypadat například takto: [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]. Jistě uznáte, že to není to pravé. Je možné si ale nadefinovat proměnné, kde budou skupinu znaků obsahovat a následně je použít asi takto ve vzoru:
$pismeno = "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]"; Znaky v množinách se speciálním významemStále to je příliš těžkopádné. Regulární výrazy nabízejí mnohem lepší řešení. Existuje totiž speciální operátor rozsahu. Ten se zapisuje v syntaxi regulárních výrazů pomlčkou. Předchozí problém s množinou všech písmen se tímto způsobem řeší mnohem pohodlněji. Do vzoru stačí uvést [a-zA-Z]. To samé lze dělat s čísly. [2-5] je totéž, co [2345]. Množninu znaků, které vyhoví číslice šetnáckového zápisu čísla, tak zapíšeme jako [0-9a-fA-F]. Zkuste si tipnout, co všechno vyhoví zápisu ^[x|y]$. Ač to možná intuitivně vypadá jako znak x nebo znak y, má tento zápis úplně jiný význam. Znak | nemá na tomto místě žádnou speciální funkci, proto celému regulárnímu výrazu vyhovuje znak x, y nebo |. Jedním z těchto speciálních znaků je ^ (negace - pozor!, se začátkem řetězce má společné jen to, že používá stejný symbol). Užijete ji, pokud například chcete definovat množinu, které mají vyhovovat všechny znaky kromě velkých písmen. Píše se bezprostředně za úvodní hranatou závorku (pokud je jinde, svoji funkci ztrácí). Má ten efekt, že to, co je obvykle množinou znaků, je jejím doplňkem. Náš problém s vynecháním velkých písmen vyřešíme takto: [^A-Z] (oproti tomu v zápisu [a-c^d-f] stříška speciální význam nemá, protože již není na 1. pozici). Stejně jako stříška ztrácí uvnitř hranatých závorek svoji funkci na jiném než 1. místě, ztrácí ji i uzavírací závorka na 1. místě. Pokud je tam uvedete, bere se jen jako znak z množiny. Je-li umístěna jinam, musíte jí předřadit zpětné lomítko. To samé platí pro pomlčku - speciální funkci má pouze, pokud dostane z obou stran nějaké smysluplné hodnoty. V opačném případě totiž buď hlásí Invalid range (je-li na jedné straně písmeno, na druhé číslo, nebo když jsou strany prohozeny), a nebo bere pomlčku jako znak bez speciálního významu (pokud je uvedena na začátku nebo na konci řetězce v hranatých závorkách). Nejen na alfanumerické znaky se může rozsah vztahovat. Lze zadat osmičkové rozpětí znaků z ASCII tabulky. Například znaky ( (osmičkový kód 050), ) (051), * (052), + (053). Následující 2 zápisy jsou ekvivalentní:
/^[()*+]$/ češtinaOperátor rozsahu se na české znaky nevztahuje. Jinak je to ale s předdefinovanými množinami znaků. Použijete-li příkaz use locale; a máte-li správně nastavené proměnné prostředí, vztahují se množiny i na národní znaky.
use locale; Je vytisknuto MATCHED, protože znak s háčkem množině vyhovuje. Zkuste nyní odstranit use locale;. Potom toto tvrzení platit nebude. Předdefinované množinyDalší elegantní řešení nabízejí předdefinované množiny znaků. Existují speciální escape sekvence, které je zastupují. Přitom se nemusejí uzavírat hranatými závorkami. Pro srovnání do tabulky zahrnuji i tečku.
Poznámka - Ekvivalenty \w a [_0-9a-zA-Z]) resp. \W a [^_0-9a-zA-Z] v poslední tabulce nejsou skutečně 100% ekvivalenty. Vzory [_0-9a-zA-Z] a \w se mají chovat stejně, ale v případě použití locales tomu tak není. Předveďme si důkaz:
use locale; Nyní zapíšeme regulární výraz pro formát 12hodinového zápisu času.
/^[01]\d[:\.][0-5]\d[:\.][0-5]\d[ ]?[pPaA][mM]$/;
Vysvětleme si, jak se tento regulární výraz vyhodnocuje:
Je tu problém. Našemu výrazu vyhoví i čas 13 - 19 hodin. Musíme použít znak |. 1. operand bude hledat, zda jsou hodiny mezi 00 a 09, pokud ne, 2.operand zjistí zda nejsou ještě mezi 10 až 12.
/^((0\d)|(1[0-2]))[:\.][0-5]\d[:\.][0-5]\d[ ]?[pPaA][mM]$/;
Regulárnímu výrazu ((0\d)|(1[0-2])) vyhovují čísla 01 až 12, zbytek je stejný jako v minulém příkladu. Celý výraz ještě o něco zjednoduší přepínač /i. Zápis [pPaA][mM] pak může vypadat o něco pohodlněji.
/^((0\d)|(1[0-2]))[:\.][0-5]\d[:\.][0-5]\d[ ]?[pa]m$/i;
Sice ani toto není dokonalé řešení (vyhoví i takové věci jako "10.10:40pM"), ale pro představu nám posloužilo. Unicode třídyToto asi nebudete nikdy potřebovat, ale koho to zajímá ať čte dál. Třída znaků se zadává pomocí zápisu \p{třída}. Pokud chceme doplněk třídy (tedy vše mimo toho, co do třídy patří), použijeme zápis \P{třída}. V 1. tabulce jsou jen pro představu 2 Unicode třídy. Existuje jich ale mnohem více (man perlretut).
Znakem měny je například dolar:
print "MATCHED" if "r" =~ /^\p{IsSc}$/; #nevyhovuje Dále si Perl některé třídy sám definuje. Mají 2 možnosti zápisu. Buď \p{třída} nebo [:třída:]. Zápis [:třída:] je možný jen uvnitř dalších [ ]. Samotné [:třída:] by totiž znamenalo množinu znaků :, t, ř, í, d, a. Je tedy nutný zápis [[:třída:]].
Použití ukazuje následující kód. Všimněte si odlišných barev hranatých závorek. Vnější definují množinu znaků, jejíž obsahem je třída xdigit.
print "MATCHED" if "5" =~ /^[[:xdigit:]]$/; #vyhovuje - 5 je hexadecimální Perl umožňuje POSIX třídy negovat. Negovaná [:třída:] je [:^třída:]. Na závěr ještě něco k definici unicode tříd. Je nutné vytvořit podprogram se stejným jménem jako třída. Jeho návratovou hodnotou jsou řádky. Je-li na řádku 1 číslo, určuje ASCII znak, určený 16kově. Jsou-li na řádku 2 čísla, oddělená mezerou, jde o rozsah. Definujeme si třídu IsZavorka, které vyhoví 1 ze znaků (, ), {, }, [, ], <, > - tedy závorka kulatá, složená, hranatá nebo lomená.
print "MATCHED" if "(" =~ /^\p{IsZavorka}$/; #vyhovuje Třídy lze definovat i pomocí již definovaných tříd. V takovém případě je do návratové hodnoty podprogramu třeba uvést řádek [+!-&]balík::Trida. Implicitní unicode třídy jsou v balíku utf8. + (sjednocení) funguje pro přidání znaků z příslušné třídy, ! (rozdíl) pro odebrání znaků, - (doplněk) pro všechny znaky mimo znaky z této třídy a & (průnik) vybere pouze znaky, které jsou v této třídě a třídě jiné. Pro definici třídy IsBracket, která má stejný význam jako IsZavorka stačí psát toto:
sub IsBracket { Další možností definice unicode tříd je podle typu písma. Existují například třídy InHebrew, InMathematicalOperators. Celý seznam je na manuálové stránce perlunicode. ZdrojeToto téma by zabralo několik samostatných článků. Mnohem více o unicode třídách a jejich definicích na manuálových stránkách
Související články
Předchozí Celou kategorii (seriál) Další
Perl (1) - Dávka teorie na úvod
Perl (2) - Úvod do syntaxe Perl (3) - Proměnné Perl (4) - Čísla a řetězce Perl (5) - Podmínky Perl (6) - Pravdivostní výrazy Perl (7) - Vstup poprvé Perl (8) - Některé základní vestavěné funkce Perl (9) - Cykly Perl (10) - Další řídící struktury Perl (11) - Pole - úvod Perl (12) - Pole - základní operace Perl (13) - Hashe Perl (14) - Další nástroje pro seznamy Perl (15) - Výchozí proměnná, heredoc, symbolické odkazy Perl (16) - Regulární výrazy - začínáme Perl (17) - Regulární výrazy - kotvy Perl (19) - Regulární výrazy - opakování a kvantifikátory Perl (20) - Regulární výrazy - magické závorky Perl (21) - Regulární výrazy - nahrazování Perl (22) - Regulární výrazy - přepínače Perl (23) - Regulární výrazy - rozšířené vzory Perl (24) - Regulární výrazy - příklady Perl (25) - Regulární výrazy - závěr Perl (26) - Podprogramy Perl (27) - Prototypy Perl (28) - Rozsahy platnosti proměnných Perl (29) - Úvod k práci se soubory Perl (30) - Práce se soubory Perl (31) - Testování souborů Perl (32) - Jiné typy souborů Perl (33) - Formátování výstupu - printf Perl (34) - Formátování výstupu - formáty Perl (35) - Vestavěný debugger Perl (36) - Grafické debuggery Perl (37) - Začínáme s moduly Perl (38) - Rozhraní modulu Perl (39) - Pragma Perl (40) - Dodatky k modulům Perl (41) - CPAN Perl (42) - Argumenty příkazového řádku Perl (43) - Přepínače Perl (44) - Dlouhé přepínače Perl (45) - Odkazy Perl (46) - Užití odkazů a anonymní data Perl (47) - Složitější datové struktury Perl (48) - Libovolně složité datové struktury Perl (49) - Tabulky symbolů a typegloby Perl (50) - Uzávěry a iterátory Perl (51) - Signály Perl (52) - Externí příkazy Perl (53) - Režim nakažení Perl (54) - Fork Perl (55) - Eval Perl (56) - Volby příkazu perl Perl (57) - Jednořádkové skripty Perl (58) - OOP - úvod Perl (59) - OOP - typické použití Perl (60) - OOP - dědičnost Perl (61) - OOP - přínos a užití dědičnosti Perl (62) - OOP - přetěžování Perl (63) - OOP - závěr Perl (64) - Projekt - čtečka sportovních výsledků Perl (65) - Projekt - získání dat Perl (66) - Projekt - výběr zápasů a podrobnosti Perl (67) - Projekt - dokončujeme modul Perl (68) - Projekt - zobrazení zápasů Perl (69) - Projekt - online přenos Perl (70) - Plain Old Documentation Perl (71) - Navazování proměnných Perl (72) - Navazování složitějších datových typů Perl (73) - DBM Perl (74) - Sockety Perl (75) - Obsluha více klientů Perl (76) - Síťová hra v kostky Perl (77) - Služby internetu Perl (78) - Databáze - úvod Perl (79) - Databáze - manipulace s daty Perl (80) - Databáze - závěrečné poznámky Perl (81) - CGI - příprava webového serveru Perl (82) - CGI - první skripty Perl (83) - CGI - získávání dat od uživatele Perl (84) - CGI - usnadnění tvorby skriptů pomocí modulu CGI Perl (85) - CGI - generování dokumentu modulem CGI Perl (86) - CGI - cookies Perl (87) - CGI - příklad aplikace Perl (88) - CGI - závěr Perl (89) - Mason - snadné psaní webů Perl (90) - Mason - speciální bloky Perl (91) - Mason - handlery Perl (92) - Mason - závěr Perl (93) - Catalyst - MVC framework pro Perl Perl (94) - Catalyst - základy pro psaní aplikace Perl (95) - Catalyst - šablony Perl (96) - Catalyst - spolupráce s databází Perl (97) - Curses - tvorba textových uživatelských rozhraní Perl (98) - Curses - pozicování a okna Perl (99) - Curses - měření rychlosti psaní Perl (100) - Curses - použití hotových widgetů Perl (101) - Curses - jednoduchý textový editor Perl (102) - Rozšiřování Perlu pomocí XS Perl (103) - Rozšiřování Perlu pomocí SWIG Perl (104) - Testování rychlosti Perl (105) - Testování programových jednotek Perl (106) - Debugování pomocí komentářů Perl (107) - Moose - moderní objektový systém Perl (108) - Moose - základní vlastnosti Perl (109) - Moose - role Perl (110) - Moose - meta API Perl (111) - Pokročilá práce se seznamy Perl (112) - Práce s PDF Perl (113) - Práce s archivy Perl (114) - Tk - úvod Perl (115) - Tk - umísťování widgetů Perl (116) - Tk - základní widgety Perl (117) - Tk - některé pokročilejší widgety Perl (118) - Tk - čas a události Perl (119) - Tk - CD man Perl (120) - Wx - základní práce s widgety Perl (121) - Wx - události Perl (122) - Gtk2 - úvod Perl (123) - Gtk2 - základní práce s obrázky Perl (124) - Gtk2 - události a čas Perl (125) - Gtk2 - vlastní widgety Perl (126) - Gtk2 - textové okno a práce s pozicemi Perl (127) - Gtk2 - hierarchické seznamy Perl (128) - Gtk2 - dialogy Perl (129) - Gtk2 - skládání widgetů Perl (130) - Gtk2 - menu a toolbary Perl (131) - Gtk2 - transparentní okna, tray ikona, výběr souborů Perl (132) - Gtk2 - drag&drop, druid Perl (133) - Gtk2 - úpravy vzhledu aplikací pomocí rc Perl (134) - Gtk2 - Glade Interface Designer Perl (135) - XML - čtení a zápis Perl (136) - XML - DOM a SAX přístupy Perl (137) - Vlákna Perl (138) - Memoizace - cachování podprogramů Perl (139) - Profilling - efektivní odhalování pomalých míst v programu Perl (140) - Profilling - píšeme si vlastní profiler / debugger Perl (141) - Formátování kódu, deparsování, perltidy Perl (142) - Způsoby konfigurování Perl (143) - Struktura datových typů, správa paměti Perl (144) - POE - událostmi řízené programování Perl (145) - POE - aplikace typu klient-server Perl (146) - Perl 6 - jazyk budoucnosti Perl (147) - Perl 6 - regulární výrazy, nové operátory Perl (148) - Perl Culture Perl (149) - Závěr Pozvánka na Český Perl Workshop Perl 5.22.0 a vše okolo Perl 5.24.0 a vše okolo Předchozí Celou kategorii (seriál) Další
|
Vyhledávání software
Vyhledávání článků
28.11.2018 23:56 /František Kučera 12.11.2018 21:28 /Redakce Linuxsoft.cz 6.11.2018 2:04 /František Kučera 4.10.2018 21:30 /Ondřej Čečák 18.9.2018 23:30 /František Kučera 9.9.2018 14:15 /Redakce Linuxsoft.cz 12.8.2018 16:58 /František Kučera 16.7.2018 1:05 /František Kučera
Poslední diskuze
31.7.2023 14:13 /
Linda Graham 30.11.2022 9:32 /
Kyle McDermott 13.12.2018 10:57 /
Jan Mareš 2.12.2018 23:56 /
František Kučera 5.10.2018 17:12 /
Jakub Kuljovsky | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2024) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze |