Gym
lesson

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.