Regularni izrazi (regex) — osnove
Cilj lekcije: Razumeti sta su regularni izrazi, nauciti osnovne metakaraktere i moci da citaes i pises jednostavne regex obrasce koji se koriste u grep, sed i drugim alatima.
Sta je regularni izraz?
Regularni izraz (skraceno: regex) je nacin da opises obrazac teksta — umesto da trazis tacno odredjenu rec, kazes "trazim bilo koji niz koji izgleda OVAKO".
Analogija: zamisli da trazis kontakt u telefonskom imeniku i kazes "trazim sve osobe cije ime pocinje sa 'Mar' i ima 4-6 slova". To je u sustini regex — ne trazis jednu konkretnu vrednost nego opisujes oblik.
Regex koristis uvek kada trebaS:
- Pronaci sve email adrese u tekstu
- Proveriti da li niz sadrzi samo cifre
- Izdvojiti sve redove koji pocinju odredjenom recju
- Promeniti deo teksta koji odgovara nekom obliku
Razlika od glob-a (kratka napomena)
Mozda si vec video * u shell-u — na primer ls *.txt. To je glob, ne regex.
| Kontekst | * znaci |
|---|---|
Shell glob (ls *.txt) |
"bilo koji niz karaktera" |
Regex (grep "go*gle") |
"nula ili vise prethodnog karaktera" |
Ovo je jedna od najcescih zabuna. Nemoj mesati — glob je za shell, regex je unutar alata kao grep, sed, awk.
Literalni karakteri
Slova, brojevi i vecina znakova se u regex-u traze doslovno — onako kako su napisani. To je i dalje regex, samo bez specijalnih simbola.
Pattern: marko
Tekst: "Zovem se marko i imam 25 godina."
Match: "marko"
Pattern: 404
Tekst: "Greska 404: stranica nije pronadjena."
Match: "404"
Kada koristis grep "greska" fajl.txt — vec koristis regex, samo bez specijalnih simbola.
Specijalni metakarakteri
Sledeci simboli imaju posebno znacenje u regex-u. Ovo su jedini koje treba da znas za pocetak.
. — bilo koji jedan karakter
Tacka odgovara tacno jednom karakteru — bilo kom (slovo, cifra, razmak, znak).
Pattern: gr.p
Tekst: "grep grap grBp gr2p gr p"
Match: "grep", "grap", "grBp", "gr2p", "gr p"
echo "grep" | grep "gr.p" # match
echo "grp" | grep "gr.p" # nema match (tacka mora da pokrije jedan karakter)
* — nula ili vise prethodnog karaktera
Zvezdica se odnosi na karakter ispred sebe i kaze "tog karaktera moze biti 0 ili vise puta".
Pattern: go*gle
Tekst: "ggle gogle google gooogle"
Match: "ggle", "gogle", "google", "gooogle"
echo "google" | grep "go*gle" # match
echo "ggle" | grep "go*gle" # match (nula 'o')
+ — jedan ili vise prethodnog (samo uz -E)
Kao *, ali mora biti bar jedno pojavljivanje.
Pattern: go+gle
Tekst: "ggle gogle google"
Match: "gogle", "google" (ali NE "ggle" — nema ni jednog 'o')
echo "google" | grep -E "go+gle" # match
echo "ggle" | grep -E "go+gle" # nema match
? — nula ili jedan prethodni (samo uz -E)
Prethodni karakter je opcionalan — pojavljuje se 0 ili 1 puta.
Pattern: colou?r
Tekst: "color colour"
Match: "color", "colour"
echo "color" | grep -E "colou?r" # match
echo "colour" | grep -E "colou?r" # match
echo "colouur"| grep -E "colou?r" # nema match (dva 'u')
^ — pocetak linije
Karet na pocetku patterna znaci "ovo mora biti na pocetku linije".
Pattern: ^Greska
Tekst: "Greska: fajl nije nadjen" -> match
Tekst: "Log: Greska u sistemu" -> nema match (Greska nije na pocetku)
echo "Greska: fajl nije nadjen" | grep "^Greska" # match
echo "Log: Greska u sistemu" | grep "^Greska" # nema match
$ — kraj linije
Dolar na kraju patterna znaci "ovo mora biti na kraju linije".
Pattern: bash$
Tekst: "/bin/bash" -> match
Tekst: "/bin/bash_old" -> nema match
echo "/bin/bash" | grep "bash$" # match
echo "/bin/bash_old" | grep "bash$" # nema match
[abc] — bilo koji od navedenih karaktera
Uglaste zagrade definisu skup — odgovara tacno jedan karakter koji je u skupu.
Pattern: [aeiou]
Tekst: "linux"
Match: "i", "u" (svaki samoglasnik posebno)
echo "linux" | grep "[aeiou]" # match (ima 'i' i 'u')
echo "trk" | grep "[aeiou]" # nema match
[a-z] — opseg karaktera
Crtica unutar zagrada definise opseg.
Pattern: [0-9]
Tekst: "telefon: 0641234567"
Match: svaka cifra posebno
echo "telefon: 0641234567" | grep "[0-9]" # match
echo "nema cifara" | grep "[0-9]" # nema match
Korisni opsezi:
[0-9]— cifre[a-z]— mala slova[A-Z]— velika slova[a-zA-Z]— sva slova[a-zA-Z0-9]— slova i cifre
[^abc] — negacija (ne ovi karakteri)
Karet unutar uglastih zagrada znaci "bilo sta osim ovih karaktera".
Pattern: [^0-9]
Tekst: "abc123"
Match: "a", "b", "c" (sve sem cifara)
echo "abc123" | grep "[^0-9]" # match (ima slova)
echo "12345" | grep "[^0-9]" # nema match (samo cifre)
\ — eskejp (doslovan karakter)
Kosa crta pre specijalnog karaktera znaci "uzmi ga doslovno, ne kao metakarakter".
Pattern: \.
Tekst: "kraj recenice."
Match: "." (doslovna tacka, ne "bilo koji karakter")
echo "kraj recenice." | grep "\." # match (tacka kao tacka)
echo "kraj recenice" | grep "\." # nema match
Bez eskejpa, . bi odgovarao bilo kom karakteru i dao lazne rezultate.
Kratki primeri sa grep-om
Ovi primeri su tu da vidis regex u kontekstu:
echo "marko" | grep "^m" # match — pocinje sa 'm'
echo "marko" | grep "[A-Z]" # nema match — nema velikih slova
echo "telefon: 0641234567" | grep -E "[0-9]+" # match — ima cifara
Preporuka za pocetak: Uvek koristi grep -E — prosireni regex podrazumeva +, ?, | i () bez eskejpa, sto je ono sto vecina ljudi ocekuje.
Cesti izvori zabune
1. Tacka znaci "bilo koji" — ako trazis pravu tacku, pisi \.
grep "www.example.com" fajl.txt # tacka = bilo koji karakter (pogresno!)
grep "www\.example\.com" fajl.txt # tacka = prava tacka (ispravno)
2. * u regex-u NIJE isto kao * u shell-u
ls *.txt # shell glob: svi fajlovi koji se zavrsavaju na .txt
grep "go*gle" f.txt # regex: ggle, gogle, google, gooogle...
3. Regex sa razmacima — navodnici su obavezni
grep "^Mar ko" fajl.txt # ispravno — navodnici cuvaju razmak
grep ^Mar ko fajl.txt # pogresno — shell vidi "^Mar" i "ko" kao dva argumenta
Rezime — tabela metakaraktera
| Metakarakter | Znacenje | Primer |
|---|---|---|
. |
Bilo koji jedan karakter | gr.p odgovara grep, grap |
* |
Nula ili vise prethodnog | go*gle odgovara ggle, google |
+ |
Jedan ili vise prethodnog (ERE) | go+gle odgovara gogle, google |
? |
Nula ili jedan prethodni (ERE) | colou?r odgovara color, colour |
^ |
Pocetak linije | ^root — linije koje pocinju sa "root" |
$ |
Kraj linije | bash$ — linije koje se zavrsavaju sa "bash" |
[abc] |
Jedan od navedenih | [aeiou] — samoglasnik |
[a-z] |
Jedan iz opsega | [0-9] — cifra |
[^abc] |
Nije iz skupa (negacija) | [^0-9] — nije cifra |
\ |
Eskejp — doslovan karakter | \. — prava tacka |
U sledecej lekciji (grep) primenjujemo ove obrasce u praksi.