Regulární výrazy, práce s textem a daty
IBlil Úvod do programování skrze Python
2015
• dnes: práce s textem
V/V . V / I / I
• priste: prače s obrázky
• příkazy pro práci s textem/obrázky
• ukázky na konkrétních příkladech
• použití dříve probíraných konstrukcí, datových struktur (seznam, slovník)
• uvažování o problémech, volba přístupu, kladení otázek
Práce s textem
Příklady:
• statistiky o studentech
• frekvenční analýza textu
• zpracování dotazníku, ankety
"O ^ O' 3/68
• v tomto kurzu pro zjednodušení pracujeme jen s anglickou abecedou
• resp. s texty bez hacku a carek
• pro zájemce viz např.
http://www.py.cz/PythonUnicodeCestina
• základ: specifikovat kódování na začátku souboru # -*- coding: utf-8 -*-
ulární výrazy: motivace
• vyhledání e-mailových adres v textu
• vyhledání odkazů v HTML dokumentu
XI i ■ x V/ ■ X l i V/ ■ X ■ X i i
• náhrada „jméno prijmem za „prijmem jméno
• změna formátu datumů
• odstranění bílých znaků
ulární výrazy: použití
• programovaní
• textové editory
V/l / V / I I v
• príkazová radka: napr. grep
• teorie: formální jazyky, konečné automaty
Nfcw SK)u. 1 GjNCdct
.SCENARIOS WERE IT [LETS f^t^VETHEDAV,
OH NO I THE klLLER tfLSTHAVE R7LLCWED HER ON VAOTOM! I
JK
BUT TO FIND THEM WElD HAVE ID
Through 'loom orMils looking no?
SCffiTHlNG rottted LIKE an *DWE55l /
& 8
& » I IP
http://xkcd.com/208/
7/68
Regulárni výrazy
• obecně používaný nástroj
• základní syntax stejná ve většině jazyků, prostředí
• následuje:
• základní syntax regulárních výrazů
• použití v Pythonu
• nerozebíráme všechny technické detaily (podrobněji viz dokumentace)
Ukázka
import re
f = open("testovaci-soubor.txt") for radek in f .readlinesO :
if re.search(r;[a-z]+@[a-z]+\.cz;, radek) print radek f. closeO
Znaky a speciální znaky
• základní znak „vyhoví" právě sám sobě
• např. „cz" v předchozím příkladě
• speciální znaky: . ~ $ * + ? { } [] \ I ()
V V "'I ■ I ■ I V ■ . V ■ V X I / O
• umožňuji konstrukci složitějších výrazu
• chceme, aby odpovídaly příslušnému symbolu =4> prefix \
"O ^ O' 10/68
Výběr ze skupiny znaků
[abc] - jeden ze znaků a, b, c
[a-z] - výběr z intervalu (malé písmeno anglické abecedy)
na začátku výběru = negace:
• ["abc] cokoliv jiného než a, b, c
5 «ŕ)C^(V
11/68
\d Čísla: [0-9]
\D Cokoliv kromě čísel: ["0-9]
\s Bílé znaky: [ \t\n\r\f \v]
\S Cokoliv kromě bílých znaků: [~ \t\n\r\f\v]
\w Alfanumerické znaky: [a-zA-Z0-9_]
\W Nealfanumerické znaky: [~a-zA-Z0-9_]
12/68
Speciální symboly
libovolný znak začátek řetězce $ konec řetězce
I alternativa - výběr jedné ze dvou možností
13/68
Jaký je význam následujících výrazů
• kocka|pes
• ~[Pp]rase$
• \d[A-Z]\d \d\d\d\d
O oakování
* nula a více opakování
+ jedno a více opakování
? nula nebo jeden výskyt
{m,n} m až n opakování
Pozn. *, + jsou „hladové", pro co nejmenší počet opakování *?, +?
< SP ► < -1 ► < ► -E -O Os O
15/68
Jaký je význam následujících výrazů?
• ~\s*Nadpis
• ~a.+a$
• \d{3}\s?\d{3}\s?\d{3}
• [a-z]+@[a-z]+\.cz
• ~To:\s*(fi|kit)(-int)?@fi\.muni\.cz
16/68
Která z následujících slov vyhoví jednotlivým výrazům?
p[ars]e p[ars]*e p["ars]e
ps
pes
pse
poe
prase
poklice
17/68
Která z následujících slov vyhoví jednotlivým výrazům?
p[ars]e p[ars]*e p["ars]e
ps X X X
pes X / X
pse / / X
poe X X /
prase X / X
poklice X X X
18/68
Kontrola tabulky v Pythonu
texty = [MpsM,"pes","pse","poe","prase","poklice"] výrazy = [ r;p[ars]e;, r;p[ars]*e;, r;p[~ars]e; ] for text in texty:
print text,
for vyraz in výrazy:
if re.search(vyraz, text): print 1, else: print 0,
print
"O ^ O' 19/68
Backreference
„odkaz" na předchozí část textu pomocí \1, \2, \3, ...
příklad: slova, která obsahují opakovaně stejnou trojici písmen (jinde než) na začátku a konci
• periferie
• starosta
jak zapsat regulární výraz? jaká další slova splňují?
20/68
Backreference a trojice písmen
seznam slov, např.
https://ucnk.ff.cuni.cz/srovnáni10.php
regulární výrazy:
• ~(. . .).*\1$
• .(...).*\1.
výstupy např.:
• bramborami
• multikulturní
• ostrost
• skaliska
"O ^ O' 21/68
Bez regulárních výrazů
Varianta „uvnitř slova":
def shoda(slovo):
for i in ranged, len(slovo)-3) :
for j in range(i+1, len(slovo)-3) if slovo [i:i+3] == slovo + return True
return False Je to ekvivalentní?
Detekce opakovaných trojic
• regulární výraz: .(...). *\1.
• kontrola podmínky: slovo[i:i+3] == slovo [j
• rozdílné chování: skleneného, kovovou, kocicich
Co je správně?
Nejasná specifikace problému...
Regulární výrazy: xkcd
[jREGEX golf:
YOU TKV10 MffltH OWE GROUP BUF NOT7BE oma£
/tí I Difl|b/ matches
SO IUR0TE ft PROGRAM
...curi tosrnycott;
50 Xh GREPPJNG FĎR fiLVBTtW LOOKUP flfGEX GOLF 50WER5.
REftU-X Tri6 í6 all /{He^-)*REjGEXGDLF/
HOUWriflWE
fcft r map Vjf
http://xkcd.com/1313/ http://www.explainxkcd.com/wiki/index.php/1313:_Regex_Golf
https://regex.alf.nu/
24/68
ulární výrazy v Pythonu
knihovna re (import re)
re.match - hledá shodu na začátku řetězce
re. search - hledá shodu kdekoliv v řetězci
(re. compile - pro větší efektivitu)
„raw string" - r'vyraz' - nedochází k interpretaci speciálních znaků jako u běžných řetězců v Pythonu
25/68
ulární výrazy v Pythonu: práce s výsledkem
• match/search vrací „MatchObject" pomocí kterého můžeme s výsledkem pracovat
• pomocí kulatých závorek () označíme, co nás zajímá
• Alice\s+(\w+)
Regulární výrazy v Pythonu: práce s výsledkem
»> m = re.match(r" (\w+) (\w+)", \
"Isaac Newton, fyzik")
»> m.group(0) ;Isaac Newton; »> m.group(1) ;Isaac;
»> m.group(2) ;Newton;
3 «r)C^(V
27/68
Substituce
nahrazení řetězce jiným výrazem
nejen statické řetězce, ale i regulární výrazy
re.sub
28/68
Rozdělení řetězce
• split - rozdělí řetězec podle zadaného podřetězce, vrací seznam částí
• join - spojení seznamu řetězců do jednoho
>» řetězec = "Holka modrooká nesedavej u potoka" »> řetězec. split ()
[;Holka;, ;modrooká;, 'nesedavej;, ;u;, ;potoka;] »> řetězec. split (; o;)
[;H;, ;lka m; , ;dr;, ;;, ;ka nesedavej u p;, ;t;, ;ka; »> řetězec. split (;ka;)
[;Hol;, ; modroo;, ; nesedavej u poto;, ;;]
29/68
Řetězce: další funkce
• find, count - vyhledávání a počítání podřetězců
• lower, upper - převod na malá/velká písmena
• ljust, rjust, center - zarovnání textu
• lstrip, rstrip - ořezání bílých znaků na začátku/konci
Práce se soubory - připomenutí
Otevírání a zavírání:
• f = open("mujsoubor.txt") - otevření pro čtení
• f = open("můjsoubor.txt", "w") - otevření pro zápis
• f.closeO - uzavření souboru
• zápis pomocí with - lepší praxe (ale pokročilejší, souvisí s výjimkami)
Ctení a zápis:
• f .readlineO - vrátí další řádek ze souboru
• f .readlinesO - vrátí seznam všech zbývajících řádků
• f .write (řetězec) - zapíše do souboru
31/68
Příklad: Zpracování HTML
• vstup: HTML soubor
• cíl: vybrat odkazy a nadpisy
• ukážeme naivní řešení se soubory, reg. výrazy
• systémovější řešení: využití knihoven pro práci zdroji, parsování HTML, "web scraping"
4427
You cant parse [X]HTML with regex. Because HTML can't be parsed by regex, Regex is not a tool that can be used to correctly parse HTML. As I have answered in HTML-and-regex questions here so many times before, the use of regex will not allow you to consume HTML. Regular expressions are a tool that is insufficiently sophisticated to understand the constructs employed by HTML. HTML is not a regular language and hence cannot be parsed by regular expressions. Regex queries are not equipped to break down HTML into its meaningful parts, so many times but it is not getting to me. Even enhanced irregular regular expressions as used by Perl are not up to the task of parsing HTML. You will never make me crack. HTML is a language of sufficient complexity that it cannot be parsed by regular expressions. Even Jon Skeet cannot parse HTML using regular expressions, Every time you attempt to parse HTML with regular expressions, the unholy child weeps the blood of virgins, and Russian hackers pwn your we bap p. Parsing HTML with regex summons tainted souls into the realm of the living, HTML and regex go together like love, marriage, and ritual infanticide. The
cannot hold it is too late. The force of regex and HTML together in the same conceptual space will destroy your mind like so much watery putty. If you parse HTML with regex you are giving in to Them and their blasphemous ways which doom us all to inhuman toil for the One whose Name cannot be expressed in the Basic Multilingual Plane: he comes. HTML-plus-regexp will liquify the nerves of the sentient whilst you observe, your psyche withering in the onslaught of horror. Reg ex-based HTML parsers are the cancer that is killing StackOverflow it is too täte it is too täte we cannot be saved the trangession of a child ensures regex will consume all living tissue (except for HTML which it cannot, as previously prophesied) dear tord help us how can anyone survive this scourge using regex to parse HTML has doomed humanity to an eternity of dread torture and security holes using regex as a tool to process HTML establishes a breach between this world and the dread realm of corrupt entities (like SGML entities, but more corrupt) a mere glimpse of the world of regex parsers for HTML will instantly transport a programmer's consciousness into a world of ceaseless screaming, he comes, the pestilent slithy reg ex-infection will devour your HTML parser, application and existence for all time like Visual Basic only worse
f inal snuf fing ofthelies of Man ALL IS LOST ALL IS LOST the popfyhe comes he-eomes ho
http://stackoverflow.com/questions/1732348/ regex-match- open- tags-except-xhtml-self -contained- tags/1732454#1732454
^ r3i ► < ► < -E ►
33/68
Příklad: Zpracování HTML
Information for applicants for students for Industry partners
Homepage
About the faculty Admission Studies Projects
Research and development
International studies
E-learning
Industrial partners
News
Contacts
Do you know:
Faculty is constructing Center for Education, Research and Innovation for tCT in Brno -CERIT".
> more about the faculty
Faculty of Informatics Masaryk University
The Faculty of Informatics with its 2.200 students offers a wide range of fields to enroll in. These are subsumed under its Bachelor, Master, and doctoral degree programs. The Bachelor programs aim to provide their students with academic basics of informatics. The objective of the Masterones isto train students in three fields ranging from theoretical informatics to information systems.
Contacts Whystudyon Fl? Personal Administration Faculty Administration fl
News
Hew open position 2012-10-24
> no re news Q RSS
puts at FI MU!
News for Be. and Mgr. students News for Phd. students News about internship abroad News about research and development News about industrial partnership
Links
Information System MU Library Fl Lecture videos "
MH^^k
go to content go to menu (. *?)
• * - „hladové" hledání („co nejvíc")
• *? - „co nejmíň"
38/68
Příklad: Jak vykrást banku?
Přesněji: Jak převzít kurzy ze stránky ČNB?
Platnost od 05.11.2012 Pořadí: 215
mé na množství kód kurz
Austrálie dolar 1 AUD 20.454
Brazílie real 1 BRL B.706
Bulharsko lev 1 BGN 12.902
Čína renminbi 1 CNY 3.162
Dánsko koruna 1 DKK 3.383
EM J euro 1 EUR 25.235
Filipíny peso 100 PHP 47rB47
477 47S
479
480
Platnos
zeměiiiĚna Austráliedola align=™right™>l<./tdxtd>ERLl2, 902 align=™r^ghtn>3rl623, 38 325,235
t od 05.11.2012 Pořadi: 2l5
množstvikódkurz
rlATJD20, 4549r 70 6BulharskolevČinarenminbi1CHYDán3kokorunaK/tdxtd>DKKEMUeurolEimFilipinypesolQQ | PHP | Aust)
• rozdělit na řádky tabulky (podle | )
• hledat trojice velkých písmen a za nimi čísla
• převést na typ float, uložit do slovníku
Nevýhody?
Příklad: Kurzy ze stránky CNB
def zjisti_kurzy(jmeno_souboru): kurzy = {}
soubor = open(jmeno_souboru) for radek in soubor .readlinesO :
if re.match(r; Aust;,radek):
for radek_tab in radek.split(; | ;): m = re.search(
r; ( [A-Z] {3}) . *right11 > ( [\d, ] +) | ; , radek_tab) kurzy[m.group(1)] =
float(re.sub(;,; ,; . ;,m.group(2)))
soubor. closeO return kurzy
41/68
Příklad: informace o studentech
Export informací z ISu (CSV soubor):
1.
2.
3.
4.
5.
6.
7.
8.
9. 10
50668;"Sukany, Martin";zk;"FI B-AP BcAP [sem 1, roc 1 421714;"Veznik, Ondrej";zk;"FI B-AP SOCI [sem 2, roc 564138;"Machala, David";zk;"FI B-AP BcAP [sem 1, roc 43583;"Mikes, Martina";zk;"FF B-FI PLIN [sem 5, cyk 1 81908;"Sulc, Tomas";zk;"FF B-FI PLIN [sem 5, cyk 1]" 844632;"Novak, Karel";zk;"FI B-IN PSK [sem 1, roc 1]" 798639;"Dunickova, Dagmar";zk;"FI B-AP SOCI [sem 1, r 195660;"Stipsky, Tomas";zk;"FI B-AP BcAP [sem 1, roc 278740;"Fojt, Roman";zk;"FI B-AP INVS [sem 3, roc 2]" ;236293;"Zachar, Samuel";zk;"FI B-IN UMI [sem 1, roc
Pozn. Příklad je „mutovaný" z důvodu ochrany osobních údajů.
42/68
Statistiky o studentech
výpis křestních jmen (abecedně seřazený) statistika studovaných oborů
43/68
Výpis křestních jmen
def krestni_jmena(jmeno_souboru) : f = open(jmeno_souboru) jména = []
for radek in f .readlinesO :
m = re.match(r;\d+\.;\d+;"\w+, (\w+);
if m: jména.append(m.group(l)) jména.sort() print " ".join(jména) f. closeO
Jiné řešení: použití split
Statistiky oborů
def obory(jmeno_souboru): f = open(jmeno_souboru) vyskyty_oboru = {} for radek in f .readlinesO :
m = re.search(r;\s(\w+) \[sem;, radek) if m:
obor = m.group(l) vyskyty_oboru[obor] = \
vyskyty_oboru.get(obor, 0)
f. closeO
for obor in vyskyty_oboru.keys(): print obor, vyskyty_oboru[obor]
Nedostatky: např. studenti studující více oborů.
Regulární výrazy: Rekapitulace
často používane:
• libovolný znak
\d čísla
\w alfanumerické znaky
\s bílé znaky
+ * opakování
~ $ začátek, konec řádku
[ ] výběr z možností
Procvičení regulárních výrazů
http: //tutor. f i . mimi . cz úloha Regulární výrazy 40 příkladů
vyhledávání, nahrazování
47/68
Analýza textu
statistiky délky slov a vět:
• x - průměr
• s - směrodatná odchylka (míra variability)
slova věty
x s x s
Starý zákon 4.3 2.3 14.9 7.8
Čapek 4.5 2.5 14.9 13.3
Pelánek 5.9 3.6 13.5 6.9
Wikipedie 5.6 3.0 14.8 8.3
Analýza textu - postup
O text —seznam délek slov (vět) O seznam délek —>► statistiky
V/ V / V V X -< I I
přímočaré reseni 1. kroku:
• procházet vstup po znacích
• pamatovat si délku aktuálního slova, věty
• speciální znak (mezera, tečka a podobně) seznamu
■» aktualizace
49/68
Imitace textu
vstup: rozsáhlý text
výstup: náhodně generovaný text, který má „podobné charakteristiky" jako vstupní text
imitace na úrovni písmen nebo slov
"O ^ O' 50/68
Náhodnostní imitace vstupního textu
I špiské to pole kavodali parnas ne nebo kdy v Dejný Odm sem
!■ ■ i r^v ■ vvx v 'III V V I X X I
uvalím se zabiji s ran stezi re, a snobe lo v ne recekovicich blova v nadrá těly jakvěmutelaji rohnutkohonebout anej Fravinci V A pěk finé houty. zal Jírakočítencej ské žil, kdDo jak a to Lorskříže si tomůžu schno mí, kto.
Kterak král kočku kupoval V zemi Taškářů panoval král a zapřísáhl se velikou přísahou že bude pochválena První pán si jí ani nevšimnul zato druhý se rychle shýbl a Juru pohladil Aha řekl sultán a bohatě obdaroval pana Lustiga koupil od něho telegram z Bombaje v Indii není o nic horší člověk nežli někdo z mých hraček Kdepak mávl Vašek rukou
"O ^ O' 51/68
-
Základní přístup
O vstupní text ^> statistiky textu
O statistiky =^ generování náhodného textu
Co jsou vhodné statistiky?
52/68
Statistiky textu
• základ: frekvence písmen (slov)
• rozšíření: korelace mezi písmeny (slovy)
příklad: pokud poslední písmeno bylo a:
• e velmi nepravděpodobné (méně než obvykle)
• 1, k hodně pravděpodobná (více než obvykle)
• základní frekvenční analýza - datová struktura slovník písmeno frekvence
• rozšířená analýza - slovník slovníků písmeno { písmeno frekvence }
generování
• podle aktuálního písmene získám frekvence
• vyberu náhodné písmeno podle těchto frekvencí -„vážená ruleta"
54/68
mitace sofistikovaněji
Recurrent Neural Networks - dokáží postihnout i složitější aspekty jazyka
básně, recepty, Wikipedia články, zdrojové kódy, ...
http://karpathy.github.io/2015/05/21/rnn-effectiveness/
PANDARUS:
Alas, I think he shall be come approached and the day When little srain would be attain'd into being never fed, And who is but a chain and subjects of his death, I should not sleep.
Second Senator:
They are away this miseries, produced upon my soul, Breaking and strongly should be buried, when I perish The earth and thoughts of many states.
DUKE VINCENTIO:
Well, your wit is in the care of side and that. Second Lord:
They would be ruled after this chamber, and
my fair nues begun out of the fact, to be conveyed,
Whose noble souls I'll have the heart of the wars.
55/68
Statistiky jmen
• data: četnosti jmen, příjmení podle roků, krajů, ...
• zdroj: Ministerstvo vnitra C R http://www.mvcr.cz/clanek/ četnost-jmen-a-prijmeni-722752.aspx
• XLS - pro zpracování v Pythonu uložit jako CSV (comma-separated values)
• doporučené cvičení
• snadno zpracovatelné
• zajímavá data
• cvičení na vymýšlení otázek
• následuje několik ukázek pro inspiraci ...
56/68
Poznámky ke zpracování
• slovník: jméno —seznam výskytů
• CSV - funkce split seznam
• normalizace (relativní výskyty jmen) - podělit součtem (pro daný rok)
• různě velké ročníky
• neúplná data u starých ročníků
"O ^ O' 57/68
o
1950 1960 1970 1980 1990 2000 2010
Rok
Vyučující IB111: JAN, JAROSLAV, JIŘÍ, MAREK, MATĚJ, NIKOLA, ONDŘEJ, RADEK, TOMÁŠ, VALDEjyiAR,> , := > , ^c
58/68
5
59/68
30
Prvni písmena
60/68
Co zajímavého můžeme z dat zjistit?
Kladení otázek - důležitá dovednost hodná tréninku.
Computers are useless. They can only give you answers. (Pablo Picasso)
61/68
Identifikace trendů
U kterých jmen nejvíce roste/klesá popularita?
co to vlastně znamená? jak formalizovat?
62/68
Nejdelší růst/pokles
Kolik let v řadě roste popularita jména
• Tobiáš - 14
• Viktorie, Ella, Sofie - 9
• Elen, Tobias - 8
Kolik let v řadě klesá popularita jména
• Jana - 26
• Martin - 21
• Petra - 11
• Zdeněk - 9
Největší skok v popularitě za 10 let
• alespoň desetinásobný nárůst popularity: Sofie, Elen, Amálie, Ella, Nicol, Nella, Tobias
• pokles alespoň o 60 %: Petra, Pavlína, Martina
150
Počet jmen s frekvenci > 0.1%
65/68
Otevřená data / Open data
• http://www.opendata.cz
• http://www.otevrenadata.
• http://www.data.gov
• http://data.gov.uk
Zpracování dat seriózněji
využití existujících knihoven:
• načítání dat ve standardních formátech: HTML, XML, JSON, CSV, ...
• operace s daty: numpy, pandas
• vizualizace: matplotlib
prostředí ipython - interaktivní prozkoumávání dat
Shrnutí
• regulární výrazy - obecně užitečný nástroj
• práce s textem, soubory, daty v Pythonu
• příklady
• kurzovní lístek
• zpracování seznamu studentů
• imitace textu
• statistiky jmen
V/V . V I XI
priste: obrázky |