IB111 Úvod do programování skrze Python Přednáška 10 Práce s textem a daty, regulární výrazy Nikola Beneš 20. listopad 2017 IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 1/23 Motivace Chceme zpracovávat data • jakou mají podobu? • text, čísla, strukturovaná data, ... o jak jsou reprezentována? • tabulka (xls, ods, csv, ...) 9 dokument (doc, odt, md, html, ...) čistý text IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 2 / 23 Základní práce s řetězci (připomenutí) text.stripO # odstraní bílé znaky ze začátku a konce text. IstripO # totéž, jen ze začátku text .rstripO # totéž, jen z konce text. strip("ABC") # odstraní zadané znaky text.split() # vytvoří seznam jednotlivých slov text. split (", 11) # dělí podle zadaného řetězce text.split(":", maxsplit=n) # jen daný počet rozdělení text.replace(x, y) # nahradí všechny výskyty x -> y text.find(s) # index výskytu s nebo -1 s in text # True/False, jestli text obsahuje s https://docs.python.org/3/library/stdtypes.html#textseq IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 3 / 23 Speciální znaky o uvádějí se znakem zpětného lomítka \ \n" # konec řádku ^ II II # jedna uvozovka V ' # jeden apostrof \t" # tabulátor \\" # jedno zpětné lomítko https://docs.python.org/3/reference/lexical_analysis.html#strings • co když chceme tuto vlastnost zpětného lomítka „vypnout"? • raw string: přidání r nebo R před řetězec • hodí se u regulárních výrazů (uvidíme za chvíli) r"dvě zpětná lomítka: \\M r'žádné speciální znaky \n \t1 IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 4 / 23 Práce se soubory (připomenutí) f = open("myfile.txt", "r") f = open("myfile.txt11, "w") f. closeO f .readlineO f .readlinesO # otevření pro čtení # otevření pro zápis # uzavření souboru # další řádek ze souboru # seznam zbývajících řádků with open(...) as f: # soubor se sám zavře na konci bloku with for line in f: # postupné procházení řádků souboru IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 5 / 23 Příklad: Četnost jmen 9 zajímají nás nejčastější jména narozených ve vybraném roce • zdroj dat: http://www.mvcr.cz • formát XLS, převedeno do CSV (uložit jako...) 9 první řádek je hlavička tabulky • na dalších řádcích je vždy jméno a četnosti podle let o jak řešit? • zjistíme si, který sloupec nás zajímá • vyčteme z něj četnost o seřadíme jména podle četnosti • vypíšeme deset nejcastejsich [ukázka] IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 6 / 23 Regulární výrazy - motivace • hledání nebo zpracování nějak strukturovaných dat • e-mailové adresy • telefonní čísla o webové odkazy • náhrada „Jméno Příjmení" za „Příjmení, Jméno" • změna formátu data (20. 11. 2017 -» 2017-11-20) o odstranění znaků určitého druhu • data v netradičním formátu, která vyžadují předzpracování • dá se řešit s dosavadními nástroji • funkce s řetězci • procházení řetězců po znacích • ale může to být obtížně napsatelné a nešikovné IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 7 / 23 Regulární výrazy - motivace Arnold Schwarzenegger se narodil 30. 7. 1947. Madonna se narodila 16. srpna 1958. Ludwig van Beethoven se narodil 16. 12. 1770. o chceme z těchto dat vyčíst, kdy má kdo narozeniny o víme, že data mají následující strukturu: 9 „jméno se narodil(a) den měsíc rok!1 • jméno je libovolná (neprázdná) posloupnost znaků o den je číslo ukončené tečkou • měsíc je buď číslo ukončené tečkou nebo jedno slovo • rok je číslo .+ se narodila? [0-9]+\. ([0-9]+\.I\w+) [0-9]+\. 9 toto je tzv. regulární výraz IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 8 / 23 Regulární výrazy Kde se s nimi setkáme? • programovací jazyky • zejména tzv. skriptovací jazyky o ale dnes už ve všech moderních jazycích • (chytřejší) textové editory • (chytřejší souborové manažery) o nástroje příkazové řádky (sed, grep, ...) o teorie: formální jazyky, konečné automaty IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 9 / 23 Regulární výrazy • způsob, jak popisovat vzory v textu • obecně používaný nástroj • základní syntax stejná nebo velmi podobná ve většině jazyků/prostředí • my si ukážeme • základní syntax 9 použití regulárních výrazů v Pythonu • nebudeme rozebírat všechny technické detaily • (podrobněji viz dokumentace) IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 10 / 23 Příklad: Emailová adresa o chceme vypsat všechny řádky ze souboru, které obsahují emailovou adresu import re with open("test.txt") as f: for line in f: if re.search(r1[a-z]+@[a-z]+\.cz1, line): print(line) • tento příklad má zatím značné nedostatky IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 11 / 23 Regulární výrazy o základní znak popisuje sám sebe • př. „cz" v předchozím příkladu • speciální znaky: ."$* + ?{}[] ()\| • umožňují konstrukci složitějších výrazů • chceme-li popsat přesně jen speciální znak, předřadíme mu zpětné lomítko př. regulární výraz \$ hledá v textu znak dolaru • zpětné lomítko dále vytváří speciální znaky ze základních IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 Regulární výrazy Hranaté závorky [] • popisují rozsah možných znaků • [abc] - jeden ze znaků a, b, c • [a-z] - výběr z intervalu (malé písmeno anglické abecedy) • [0-9] - jedna číslice • ~ na začátku výběru - negace • ["abc] - cokoli kromě a, b, c IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 13 / 23 Regulární výrazy Často používané skupiny znaků • \d - číslice • \D - cokoli kromě číslic • \w - „znaky ve slovech" (alfanumerické znaky) • \W - cokoli kromě alfanumerických znaků • \s - bílé znaky (mezery, tabulátory, ...) • \S - cokoli kromě bílých znaků IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 14 / 23 Regulární výrazy Speciální symboly • . - libovolný jeden znak • ~ - začátek řetězce • $ - konec řetězce Skupiny • (, ) - závorkování, vytvoření skupiny (více za chvíli) • I - alternativa (nebo) Opakování • * - nula nebo více opakování předešlé části výrazu • + - jedno nebo více opakování předešlé části výrazu • ? - nula nebo jeden výskyt předešlé části výrazu • ím,n} - m až n opakování předešlé části výrazu (lze i {n}) Poznámka: * a + jsou „hladové", pro co nejmenší počet opakování *? a +? IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 15 / 23 Regulární výrazy Jaký je význam následujících výrazů? o kočka I pes • ~[Pp]rase$ • \d[A-Z]\d \d{4} • ~\s*Nadpis • ~a.+a$ • \d{3}\s?\d{3}\s?\d{3} • [a-z]+@[a-z]+\.cz • To:.*(fi|ktp)(-int)?@fi\.muni\.cz IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 16 / 23 Regulární výrazy Backreference • odkaz na předchozí skupinu • (z teoretického hlediska tohle není regulární) a ~(...).*\l$ • (.+)\1 IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 17 / 23 Regulární výrazy v Pythonu • knihovna re (import re) • re.match hledá výskyt na začátku řetězce • re.search hledá výskyt kdekoli v řetězci • re.findall hledá všechny výskyty v řetězci • re.sub nahradí výskyty regulárního výrazu zadaným řetězcem • (re.compile - předkompiluje regulární výraz pro větší efektivitu) • využijeme „raw string" - r'regulární výraz', aby nedocházelo k interpretaci speciálních znaků (zejména \) IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 18 / 23 Regulární výrazy v Pythonu • match/search vrací speciální objekt • přístup k jednotlivým skupinám pomocí metody group m = re.match(r1(\w+) (\w+)1, "Isaac Newton, fyzik") print(m.group(0)) print(m.group(1)) print(m.group(2)) IBlll prednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 19 / 23 Regulární výrazy v Pythonu • v substituci můžeme používat zpětné reference \1 apod. print(re.sub(r'(\w+) (\w+)1, r'\2, "Isaac Newton")) IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 20 / 23 Příklad: Lepší hledání emailů v textu 9 chceme vypsat jen nalezené emaily • chceme hledat emaily složitějších tvarů IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 21 / 23 Příklad: Počítání bodů v bloku o máme zadaný text, který je obsahem ISovského bloku • chceme sečíst všechny body v bloku • body jsou ve tvaru *číslo • složitější varianta: • máme exportovaný blok ve tvaru učo: jméno: obsah bloku o chceme sečíst body v bloku pro každého studenta IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 22 / 23 Příklad: hromadné přejmenování souborů o máme soubory se jmény něcol .txt až necoll7.txt • chceme je přejmenovat tak, aby se pěkně řadily podle čísla použijeme tvar něcoOOOl .txt • jak přejmenovat všechny? IBlll přednáška 10: práce s textem a daty, regulární výrazy 20. listopad 2017 23 / 23