Arvutiteaduse instituut
  1. Kursused
  2. 2025/26 sügis
  3. Programmeerimine (LTAT.03.001)
EN
Logi sisse

Programmeerimine 2025/26 sügis

  • Üldinfo
  • 1. Muutuja ja avaldis
  • 2. Tingimuslause
  • 3. Funktsioon
  • 4. Korduslause
  • 5. Sõned. Lihtsam failitöötlus
  • 6. Kontrolltöö 1
  • 7. Järjend
  • 8. Järjend 2
  • 9. Kahekordne tsükkel. Failitöötlus
  • 10. Andmestruktuurid
  • 11. Andmestruktuurid 2
  • 12. Kontrolltöö 2
  • 13. Objektorienteeritud programmeerimine
  • 14. Objektorienteeritud programmeerimine 2
  • 15. Rekursioon
  • 16. Kordamine. Projektide esitlused
  • Viiteid
  • Silmaringimaterjalid

Arhiveeritud esialgsed silmaringimaterjalid

  1. Standardteek ja moodulid
  2. Rakendusliidesed
  3. Regulaaravaldised
  4. Andmebaasid
  5. Veebirakenduste loomine
  6. Objektorienteeritud programmeerimine
  7. Graafiliste mängude loomine
  8. Keerulisemad Pythoni võimalused
  9. Võistlusprogrammeerimine
  10. Veebisisu parsimine
  11. Pilditöötlus
  12. Pythoni siseehitus
  13. Helitöötlus
  14. Kodeerimine ja krüpteerimine
  15. NumPy
  • Materjalid

3. Regulaaravaldised

Paljud programmeerijatel ette tulevad ülesanded on seotud sõnade ja teksti analüüsiga. Sellised ülesanded võivad osutuda üpris keeruliseks. Näiteks, kuidas teha kindlaks, et kasutaja sisestas ikka korrektse e-posti aadresi? Kuidas leida üles tekstist kõik telefoninumbrid? Kuidas[1] eemaldada[5] Vikipeedia[15] artiklist[43] kõik[119] viited[327]? Neid ülesandeid võib ju proovida puhta Pythoniga lahendama hakata, aga selliseid ja keerukamaidki ülesandied on palju lihtsam ja kiirem lahendada regulaaravaldistega.

Ettevalmistus

Selle peatüki läbimiseks piisab Pythoni installatsioonist.

Et peatükist aru saada, peab läbima õpiku esimesed 3 peatükki ja tutvuma järjenditega 7. peatükist.

Regulaaravaldised

Regulaaravaldis on lihtsalt muster erinevatest sümbolitest, mille abil sõnede osasid otsida.  

Kõige lihtsam regulaaravaldise muster oleks mingi sõna ise. Näiteks mustriga "koer" saab teha kindlaks, kas sõne algab osasõnega "koer", leida sõnest kõik osasõne "koer" esinemised või asendada sõnes kõik osasõned "koer" millegi muuga.

Selliseid ülesandeid on muidugi lihtne täita ka Pythonisse sisseehitatud funktsioonidega, vastavalt sõne meetodid startswith(), find() ja replace(). Ülesanne muutub keeruliseks, kui otsitav muster ei ole lihtsalt mingi sõne. Näiteks, kuidas leiame kõik neljatähelised sõnad, mis algavad k-tähega ja lõppevad r-tähega?

Suvalisi sümboleid saab regulaaravaldistes märkida punktiga. Eelmises lõigus esitatud küsimuse vastuseks sobib muster "k..r".

Regulaaravaldisi saab katsetada lehekülgedel https://regexr.com/ ja https://regex101.com. Ülemisse tekstikasti kirjuta muster ja alumisse kirjuta tekste, millega mustrit katsetada. Mustrile vastavad osad värvitakse ära ning nende peale vajutades saab lisainfot. Katseta edaspidi kõik regulaaravaldiste oskused nende rakendustega läbi.

Erinevaid viise sümbolite tähistamiseks mustrites

Saime teada, et punktidega tähistatakse ükskõik mis sümboleid. Kui meile sobivad ainult mõned sümbolid, kasutame nurksulgi. Nende sisse lähevad sümbolid, mida otsime.

SümbolTähendus
.Sobivad kõik sümbolid.
[abc]Sobivad sümbolid a, b ja c. Nurksulgude vahele võib kirjutada mistahes sümboleid.
[a-z]Sobivad tähed a kuni z ladina tähestikus.
[A-Za-z0-9]Sobivad tähed A kuni Z, a kuni z ja numbrid 0-9.
\wSobivad kõik numbrid ja tähed (k.a täpitähed) ja alakriipsud.
\dKõik arvud. Sama, mis [0-9].

Näited:

MusterSobivadEi sobi
koerkoerkõik muu
k..rkoer, kaer, koor, k03r, ...koger, kass, kor, kr, ...
[ktpb]asskass, tass, pass, basskõik muu
[0-9][0-9][0-9][A-Z][A-Z][A-Z]123ABC, 420BLZ, 111YKS jms tavalised auto numbrimärgidkõik, mis ei ole tavalised auto numbrimärgid
\w\w\w\w\w\wkõik 6-tähemärgilised sõnad, mis sisaldavad tähti, numbreid ja alakriipsekõik muu
Enesekontroll

Üks või teine, grupeerimine

Erinevate tähtede võimalusi sai määrata nurksulgudega. Pikemaid võimalusi tuleb eraldada püstkriipsudega ja vajadusel paigutada sulgude sisse.

SümbolTähendus
|Või-märk. Sobib vasakule poole jääv grupp või paremale poole jääv grupp.
()Grupeerimismärgid. Grupid tuleb ümbritseda sulgudega.

Näited:

MusterSobivadEi sobi
koer|kasskoer, kasskõik muu
k(oer|ass)koer, kasskõik muu
k(o|a)erkoer, kaerkõik muu
(ko|ka)(er|ss)koer, kass, kaer, kosskõik muu
(je|bo|ka)ssjess, boss, kasskõik muu
aias sadas (sai|leib)aaias sadas saia, aias sadas leibakõik muu
Enesekontroll

Kordused

Mustris saab veel ära määrata, et mõni sümbol või grupp saab olla sõnes mitu korda.

SümbolTähendus
?Eelnev sümbol/grupp kas on või ei ole.
*Eelnevat sümbolit/gruppi on null või rohkem kordi.
+Eelnevat sümbolit/gruppi on üks või rohkem kordi.
{5}Eelnevat sümbolit/gruppi on täpselt 5 korda.
{5,}Eelnevat sümbolit/gruppi on 5 või rohkem kordi.
{1,5}Eelnevat sümbolit/gruppi on 1 kuni 5 korda (1 ja 5 kaasa arvatud).

Näited:

MusterSobivadEi sobi
jaa?ja, jaakõik muu
(mitte )?ollaolla, mitte ollakõik muu
ja*j, ja, jaa, jaaa, ...kõik muu
ja(ja)*ja, jaja, jajaja, ...kõik muu
ja+ja, jaa, jaaa, jaaaa, ...kõik muu
ja{2,4}jaa, jaaa, jaaaakõik muu
[0-9]{3}[A-Z]{3}tavalised auto numbrimärgidmitte tavalised auto numbrimärgid
\w{6}kõik 6-tähemärgilised sõnad, mis sisaldavad tähti, numbreid ja alakriipsekõik muu
.+kõik sõned, kus on vähemalt midagitühisõne
Enesekontroll

Algus ja lõpp

Et täpsustada sõne algust ja lõppu, on olemas märgid ^ ja $.

SümbolTähendus
^Sõne algus.
$Sõne lõpp.

Näited:

MusterSobivadEi sobi
^aaabits..., arvuti..., algebra..., a123..., a...muude sümbolitega algavad sõned
ass$...kass, ...bass, ...kontrabass, ...muude sümbolitega lõppevad sõned
^koer$koerkõik muu

Erisümbolid

Oleme vaadanud palju erisümboleid, millega regulaaravaldise mustreid koostada:

. [ ] \ | ( ) ? * + { } ^ $

Aga kuidas neid sümboleid sõnedes otsida? Samamoodi, nagu Pythonis tehakse sõne sees jutumärke, saab ka regulaaravaldistes teha erisümboleid: nende ette tuleb panna langkriips. Inglise keeles öeldakse selle kohta escaping. Lühidalt: et otsida punkti, peab otsima "\.", küsimärgi otsimiseks peab otsima "\?", plussi otsimiseks "\+" jne.

MusterSobivadEi sobi
\.\.\....kõik muu
youtube\.comyoutube.comkõik muu
\(.*\)(kass), (koer), (abc123), ...mitte sulgudes olevad sõned
\[\d+\][1], [42], [1632], ...[], mitte nurksulgude vahel olevad arvud
¯\\_\(ツ\)_\/¯¯\_(ツ)_/¯kõik muu

Harjutamine

Regulaaravaldisi saab harjutada leheküljel RegexOne. Proovi ka regulaaravaldiste ristsõnu või golfi.

Regulaaravaldised Pythonis

Kasutame regulaaravaldisi lõpuks praktikas. Et Pythonis regulaaravaldisi kasutada, tuleb importida moodul re. Selle nimi on lühend ingliskeelsest terminist regular expressions.

>>> import re

Mustreid defineeritakse justkui sõnesid, aga jutumärkide ette tuleb panna r-täht. See lubab sõnedes kasutada langkriipse ilma teise langkriipsuta.

>>> muster = r"\[\d+\]"
>>> muster
'\\[\\d+\\]'

Sõne vastavus mustriga

Uurime, kas muster "k..r" vastab erinevatele sõnedele. Seda saab teha funktsiooni re.match() abil. See funktsioon tagastab objekti, kui sõne vastab mustrile. Vastasel juhul ei tagasta see midagi.

>>> muster = r"k..r"
>>> re.match(muster, "koer")
<re.Match object; span=(0, 4), match='koer'>
>>> re.match(muster, "kaer")
<re.Match object; span=(0, 4), match='kaer'>
>>> re.match(muster, "kass")
>>> 

Tegelikult kontrollib re.match() ainult, kas muster vastab sõne algusele. Et kontrollida tervet sõne, on mõistlik ette panna ^ ja taha $.

>>> re.match(r"k..r", "koerad")
<re.Match object; span=(0, 4), match='koer'>
>>> re.match(r"^k..r$", "koerad")

Seda saab ära kasutada if-lausetes:

import re

kasutajanimi = input("Sisesta kasutajanimi: ")
kasutajanimi_regex = r"^[a-z0-9_-]{3,20}$"

if re.match(kasutajanime_regex, kasutajanimi):
    print("See kasutajanimi sobib!")
else:
    print("See kasutajanimi ei sobi.")

Millised kasutajanimed programmile meeldivad? Proovi erinevaid variante.

Sarnast kontrolli saab teha e-posti aadressidega, aga muster on keerulisem:

# https://emailregex.com/
email_regex = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"

Proovi muuta programmi nii, et kontrollitakse telefoninumbri korrektsust.

Mustrite otsimine sõnedes

Funktsioon re.findall() leiab üles tekstist kõik mustri vastavused:

>>> tekst = "koer kass kaer koor koger k03r k??r"
>>> muster = r"k..r"
>>> re.findall(muster, tekst)
['koer', 'kaer', 'koor', 'k03r', 'k??r']

Proovi leida tekstist erinevaid mustreid: auto numbrimärgid, kasutajanimed, e-posti aadressid, telefoninumbrid.

Mustrite asendamine sõnedes

Funktisooniga re.sub() (sõnast substitute) saab asendada tekstis kõik mustri vastavused:

>>> tekst = "koer kass kaer koor koger k03r k??r"
>>> muster = r"k..r"
>>> asendus = "kass"
>>> re.sub(muster, asendus, tekst)
'kass kass kass kass koger kass kass'

Selle koodiga asendasime kõik mustrile "k..r" vastavad osasõned sõnega "kass".

Kopeerisid Vikipeediast pika artikli, aga teksti sisse jäävad nurksulgudes viited.

>>> tekst = "Python was conceived in the late 1980s[34] by Guido van Rossum at Centrum Wiskunde & Informatica (CWI) in the Netherlands as a successor to the ABC language (itself inspired by SETL),[35] capable of exception handling and interfacing with the Amoeba operating system.[8] Its implementation began in December 1989.[36]"

Nende eemaldamine manuaalselt on tüütu ja neid koodiga eemaldada võib esmapilgul tunduda keeruline, aga regulaaravaldised teevad selle väga lihtsaks:

>>> muster = r"\[\d+\]"
>>> re.sub(muster, "", tekst)
'Python was conceived in the late 1980s by Guido van Rossum at Centrum Wiskunde & Informatica (CWI) in the Netherlands as a successor to the ABC language (itself inspired by SETL), capable of exception handling and interfacing with the Amoeba operating system. Its implementation began in December 1989.'

Veel regulaaravaldisi?

Regulaaravaldistega on muidugi võimalik palju rohkem teha. Sellel kursusel rohkemat ei käsitleta. Regulaaravaldisi vaadatakse põhjalikumalt aines "Automaadid, keeled ja translaatorid" (LTAT.03.006).

Üks kasulik mainimata jäänud regulaaravaldise võimalus on gruppidest väärtuste saamine.

Tasub ka uurida mooduli re dokumentatsiooni: https://docs.python.org/3/library/re.html 

Enesekontrolliküsimused

Ülesanded

1. Kirjuta programm numbrileidja.py, mis leiab failist üles kõik telefoninumbrid järgmise vorminguga:

  • Alguses on +372, aga mitte alati.
  • Järgmisena võib tulla tühik.
  • Järgmisena tuleb 3 või 4 numbrit.
  • Järgmisena võib tulla tühik.
  • Järgmisena tuleb 4 numbrit.

Mõne telefoninumbri näited:

  • +372 1234 5678
  • 1234 5678
  • 123 4567
  • +37212345678
  • +3721234567
  • +372 12345678
  • +372123 4567

Näiteks kontakt.txt sisu (andmed pärit Riigikogu leheküljelt):

Riigikogu
Henn Põlluaas +372 631 6301 henn.polluaas@riigikogu.ee
Helir-Valdor Seeder +3726316311 helir-valdor.seeder@riigikogu.ee
Siim Kallas +372 6316321 siim.kallas@riigikogu.ee
Tiiu Pohl 6316302 tiiu.pohl@riigikogu.ee

numbrileidja.py käivitamine:

Sisesta failinimi: kontakt.txt
Leitud telefoninumbrid:
+372 631 6301
+3726316311
+372 6316321
6316302
  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Õppematerjalide varalised autoriõigused kuuluvad Tartu Ülikoolile. Õppematerjalide kasutamine on lubatud autoriõiguse seaduses ettenähtud teose vaba kasutamise eesmärkidel ja tingimustel. Õppematerjalide kasutamisel on kasutaja kohustatud viitama õppematerjalide autorile.
Õppematerjalide kasutamine muudel eesmärkidel on lubatud ainult Tartu Ülikooli eelneval kirjalikul nõusolekul.
Courses’i keskkonna kasutustingimused