"""Vyhledávání slov textu, vytvoření konkordančních řádků (hledaná slova v kontextu např. 3 slov zleva a zprava), uložení takto vytvořených konkordančních řádků, nahrazování (např. "ch" za X), RE""" # nacteni obsahu z existujiciho souboru with open('C:\\Users\\Cech\\00_prace\\vyuka\\Brno\\PLIN057_stroj_zprac_textu\\text_01.txt', encoding='UTF-8') as f: obsah = f.read() print(obsah) # nahrazeni vice znaku text_bez_interpunkce = obsah.translate(str.maketrans({',':'', '.':'', '!':'', '?':''})) print(text_bez_interpunkce) text_bez_interpunkce_lc = text_bez_interpunkce.lower() print(text_bez_interpunkce_lc) # prace s RETEZCEM # zjisteni poctu urcitych znaku ci slov (de facto rezecu) text_bez_interpunkce_lc.count("a") #pocet pismen a text_bez_interpunkce_lc.count(" a ") #pocet slov a (tj. vsech a mezi mezerama) text_bez_interpunkce_lc.count(" že ") # rozumnejsi je ale pracovat s textem jako se SEZNAMEM # protoze jde napr. vetsinou o to vyhledat slova a jejich okoli text = text_bez_interpunkce_lc.split() print(text) #zjisteni, zda je dane slovo v textu, jen cele polozky seznamu 'a' in text 'vám' in text 'vá' in text #false -> musi to byt cela polozka seznamu 'email' in text #UKOL: vytvorte promennou 'hledane slovo', do ni zapiste slovo 'světadílu' # zjistete, zda se nachazi v danem textu # pokud ano, vytisknete vetu (napr. pomoci f-string) "Slovo XY je v textu" # pokud ne, vytisknete vetu (napr. pomoci f-string) "Slovo XY není v textu" # pouzijte if, else hledane_slovo = 'světadílu' if hledane_slovo in text: print(f"Slovo '{hledane_slovo}' je v textu") else: print(f"Slovo '{hledane_slovo}' není v textu") # UKOL: zjistěte, která slova obsahují řetězec písmen "vá", # vypište na každý řádek větu: Slovo XY obsahuje 'vá'") # (viz vyhledavani v ramci reteczcu) for slovo in text: if 'vá' in slovo: print(f"Slovo '{slovo}' obsahuje 'vá'") # UKOL: zmente predchozi skript, tak aby vytvoril seznam slov (typů) osahující daný retezec # tento seznam ulozte do promenne 'hledana slova' # kolik je tam takových výrazů? hledana_slova = [] for slovo in text: if 'vá' in slovo: hledana_slova.append(slovo) print(list(set(hledana_slova))) #zvazit: neni treba prevadet mnozinu na seznam, # print si poradi i s vytistenim mnoziny, tj. "print(set(hledana_slova))"; jediny # rozdil pak bude v tom, ze se do konzole vypisou slova ohranicena kudrnatyma # zavorkama (set), namisto hranatych (list) # - moznav teto souvislosti rict vic o mnozinach, kod by sel zapsat i takto: # hledana_slova = set() # for slovo in text: # if 'vá' in slovo: # hledana_slova.add(slovo) # print(hledana_slova) # UKOL: zjistete pocty slov 'že', 'en' a 'jsou' v textu # pouzijte sezna, print(text.count('že')) print(text.count('en')) print(text.count('jsou')) #UKOL: zjistete pocet slov ze seznamu text obsahujich dany retezec, vypsat to do formy: # V textu je XY slov obsahujících retezec abs hledany_retezec = 'vá' pocet = 0 for slovo in text: if hledany_retezec in slovo: pocet += 1 print(f"V textu je {pocet} slov obsahujích '{hledany_retezec}'.") # KONKORDANCNI RADKY (to jsou radky, kde se vraci i okoli hledaneho slova) # budu pro to pouzivat zkratku kwic, jak je bezne v korpusove lingvistice # zjistim indexy/pozice hledaneho slova # ALE pripomenout nejdriv predhozi lekci, napr. jim dat vyhledat 1.-10., 8-13 slovo v textu, posledni nebo posledni 3 # bez toho, aby to chapali kwic neudelaji print(text[0:10]) #posledni se nezahrnuje print(text[7:13]) print(text[-1]) print(text[-3:]) #nemuze se napsat [-3:-1], protoz posledni element intervalu se nezahrnuje # struktura slicingu [start:stop:step] # https://www.simplilearn.com/tutorials/python-tutorial/python-slicing#what_is_slicing print(text[::1]) # vypise kazde ctvrte slovo print(text[::4]) # vytvoreni seznamu pozpatku print(text[::-1]) #(start == posledni index, stop == prvni index, tj. 0) # nejdriv vysvetleni enumerate # https://naucse.python.cz/lessons/beginners/zip-enumerate/ enumerate(text) list(enumerate(text)) # vypisem poradi slov for por_slovo in enumerate(text): poradi, slovo = por_slovo print(f'{poradi+1}. slovem v textu je "{slovo}".') # a ted zpet ke KWIC # indexy/pozice hledaneho slova hledane_slovo = 'vám' pozice = [] for i, slovo in enumerate(text): # enaumerate pracuje jak s indexem, tak se slovem if slovo == hledane_slovo: pozice.append(i) print(pozice) # puvodni varianta hledane_slovo = 'vám' pozice = [] for i in range(len(text)): #range vytvari sled cisel, defaultne pocita od nuly a nezapocitava posledni cislo e.g. range(166) -> 0-165 (nicmene provede 166x) if text[i] == hledane_slovo: #asi by bylo lepsi to udelat pres nejakou def, aby se to dalo zadat pozdeji pozice.append(i) print(pozice) #vytisknu si jednotliva slova a jejich okoli #nejdrive jednotliva slova for i in pozice: print(text[i]) #a pridavam 1 slovo za for i in pozice: print(text[i:i+2]) #cisly nastavim velikost rozsahu, pripomenout, ze posledni hodnota se nezahrnuje, proto je treba pridat +1 #a pridavam 5 slov za for i in pozice: print(text[i:i+6]) #UKOL. vytvorte seznam, ktery bude mit hledane slovo a tri slova pred sebou for i in pozice: print(text[i-3:i+1]) #opet, nemuze tam byt vpravo 'i', protoze pravy index se nezahrnuje #UKOL. vytvorte seznam, ktery bude mit hledane slovo a 6 slov pred sebou a za sebou for i in pozice: print(text[i-6:i+7]) #cisly nastavim velikost rozsahu #kwic se lip cte jako prosty text, tak musim ze seznamu udelat retezec priklad = ['do', 'historie', 'našich', 'národů', 'hovořím', 'k', 'vám', 'v', 'prvních', 'hodinách', 'roku', 'nového', 'a'] print(' '.join(priklad)) #prevedu seznam na text for i in pozice: print(' '.join(text[i-6:i+7])) #UKOL: a s hledanym slovem mezi zobacky (tak se to casto vyznacuje v korp. lingv.) for i in pozice: print(f"{' '.join(text[i-6:i])} <{text[i]}> {' '.join(text[i+1:i+7])}") #vytvoreni seznamu, kde budou jednotlivymi polozkami jednotliva kwic seznam_kwic = [] for i in pozice: seznam_kwic.append(' '.join(text[i-6:i+7])) print(seznam_kwic) #a ted to dame vse dohromady, aby se to dalo pouzit pro jakekoliv slovo a rozsah hledane_slovo = 'světadílu' levy_kontext = 3 pravy_kontext = 3 pozice = [] seznam_kwic = [] for i in range(len(text)): #range vytvari sled cisel, defaultne pocita od nuly a nezapocitava posledni cislo e.g. range(166) -> 0-165 (nicmene provede 166x) if text[i] == hledane_slovo: seznam_kwic.append(' '.join(text[i-levy_kontext:i+pravy_kontext+1])) print(seznam_kwic) #!!!je tu problem v pripade, ze se dane slovo vyskytne napr. na zacatku textu a dame vyhledavani slov pred nimm napr. zkus rok vs spoluobčané # vrati to IndexError: list index out of range #dalo by se to vyresit tim, ze se na zacatek a konec textu (v nasem pripade seznamu) prida pocet polozek odpovidajici rozsahu #ukazka priklad = ['do', 'historie', 'našich', 'národů', 'hovořím'] a = 0 b = 0 levy_kontext = 3 pravy_kontext = 3 while a < levy_kontext: priklad.insert(0, ' ') a += 1 while b < pravy_kontext: priklad.append(' ') b += 1 print(priklad) #a ted uz cele hledane_slovo = 'drazí' #funguje to i pro prvni a posledni slovo levy_kontext = 5 pravy_kontext = 3 pozice = [] seznam_kwic = [] a = 0 b = 0 while a < levy_kontext: text.insert(0, ' ') a += 1 while b < pravy_kontext: text.append(' ') b += 1 for i in range(len(text)): #range vytvari sled cisel, defaultne pocita od nuly a nezapocitava posledni cislo e.g. range(166) -> 0-165 (nicmene provede 166x) if text[i] == hledane_slovo: seznam_kwic.append(' '.join(text[i-levy_kontext:i+pravy_kontext+1])) print(seznam_kwic) #Michalova varianta hledane_slovo = 'drazí' levy_kontext = 3 pravy_kontext = 3 pozice = [] seznam_kwic = [] for i, slovo in enumerate(text): if slovo == hledane_slovo: start = max(0, i-levy_kontext) end = min(i+pravy_kontext+1, len(text)) seznam_kwic.append(' '.join(text[start:end])) print(seznam_kwic) #zapsani vysledku do txt souboru a jeho ulozeni, nacitani textu, je to podobne with open('output.txt', mode='w', encoding='utf-8') as file_to_save: for line in seznam_kwic: print(line, file=file_to_save) with open('C:\\Users\\Cech\\00_prace\\vyuka\\Brno\\PLIN057_stroj_zprac_textu\\output.txt', mode='w', encoding='utf-8') as file_to_save: for line in seznam_kwic: print(line, file=file_to_save) #RE - udelam nejaky uvod # cviceni na RE: https://regexone.com/ # https://docs.python.org/3/library/re.html # Michal: import re # help(re) #https://docs.python.org/3.9/library/re.html #budeme pracovat retezci, tj. puvodnim textem, ktery jsme tokenizovali vyse #jednoduche zjisteni, zda se dany retezec vyskytuje v textu #funkce hlasi jen prvni vyskyt, ale to je ted jedno print(text_bez_interpunkce_lc) slovo = "vám" if re.search(slovo, text_bez_interpunkce_lc): print(f"je tam slovo '{slovo}'") else: print(f"není tam slovo '{slovo}'") #vysvetlit: symboly \w, \b atd. http://programujte.com/clanek/2007110100-regularni-vyrazy-v-pythonu-1-cast/ #vysvetlit: ., *,+,[],\,|,^,{},?, $ #vyhneme se dvema zpetnym lomitkum #r' řekne pythonu, vykašli se na escape sekvence, čti to jako znaky #je treba se podivat na seznam tec symbolu https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals #ukolem bude najit vsechna slova obsahujici urcite rezce, pujdem krok za krokem #re.findall() vraci seznam, jen retezce, ktere se napisi hledane_retezce = r'žs' #vrati jen tyto retezce slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #prida z kazde strany jeden znak hledane_retezce = r'.žs.' slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #je to moc zrave, vrati cely text, musime to omezit na hranice slova hledane_retezce = r'.*žs.*' slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #cokoliv krome pismena, pismen <0,>, takze najde zacatek slova po dany retezec hledane_retezce = r'\w*žs' slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #vrati cela slova obsahujici damy retezec hledane_retezce = r'\w*žs\w*' slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #to same, jen za pomoci hranice slov hledane_retezce = r'\w*žs\w*' slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #je treba se podivat na seznam tec symbolu https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals hledane_retezce = r'\w*žs\w' slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #UKOL: vyhledat slova začínající na 'ne-'a hledane_retezce = r'\bne\w*' slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #vyhledat slova začínající na 'ne-'a # !!! jen v seznamech hledane_retezce = r'^ne' #?proc nefunguji ^ a $? protoze znaky ^ a $ oznacuji zacatek/konec celeho retezce slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #ÚKOL: vyhledat slova začínající na 'zá-'a zakončená na '-m' hledane_retezce = r'\bzá\w*m\b' slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #UKOL vyhledat slova v délce 1 písmene hledane_retezce = r'\b\w\b' slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #UKOL vyhledat slova v délce 2 nebo 3 písmena hledane_retezce = r'\b\w{2,3}\b' slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #UKOL vyhledat slova v delší než 10 písmen hledane_retezce = r'\b\w{10,}\b' slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #vyhledat vyrazy obsahující číslice hledane_retezce = r'\b\d+\b' #najde ale jen vyrazy z cislic slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty) #vyhledat vyrazy obsahující číslice hledane_retezce = r'\w*\d\w*' slovo_vyskyty = re.findall(hledane_retezce, text_bez_interpunkce_lc) print(slovo_vyskyty)