Kvantifikatori u regularnim izrazima

U ovoj lekciji ćemo naučiti kako da definišemo veći broj znakova u šablonu. Do sada smo učili razne načine da definišemo znak - zadajući znak kao literal, preko metaznakova ili kao klasu. Prava moć regularnih izraza, krije se u mogućnosti da odredimo da se tako definisan znak može ponoviti više puta.

Ponavljanje znakova se zadaje tako što se iza znaka koji se može ponavljati, doda posebna oznaka, tzv. kvantifikator, koji određuje koliko puta se znak može ponoviti. Počećemo od najkorišćenijih.

Z? zadati znak se može pojaviti jednom ili nijednom
Z+ zadati znak se može pojaviti jednom ili više puta
Z* zadati znak se može pojaviti nijednom, jednom ili više puta
Z+? zadati znak se može pojaviti jednom ili više puta uz lenjo uparivanje
Z*? zadati znak se može pojaviti nijednom, jednom ili više puta uz lenjo uparivanje

U primerima koji slede, objasnićemo svaku od ovih varijanti. Tekst, šablone i modifikatore u primerima slobodno možete menjati, kako biste videli šta se dešava.

Šablon bez kvantifikatora bar[ak]a ig Ova bara je mesto gde plovi barokna barka, kao i barža, ali samo dok je baraka zatvorena. Pvo da vidimo kako bi izgledalo bez kvantifikatora. U šablonu smo definisali da počinje slovima "bar", onda ide jedan znak koji može biti "k" ili "a" i na kraju se obavezno nalazi znak "a". Kao što vidimo, selektovana je samo reč "barka", pošto se jedina uklapa u šablon (mogla bi i reč "baraa", kada bi postojala).
Znak se pojavljuje jednom ili nijednom bar[ka]?a ig Ova bara je mesto gde plovi barokna barka, kao i barža, ali samo dok je baraka zatvorena. Definisali smo da šablon počinje slovima "bar", onda ide znak koji može biti "k" ili "a" i taj znak se javlja jednom ili nijednom (zahvaljujući kvantifikatoru ?) i na kraju se obavezno nalazi znak "a". Pronađen je tekst "barka" i dva puta tekst "bara" (pošto sada znak između "bar" i "a" može i da ne postoji).
Znak se pojavljuje jednom ili više puta bar[ka]+a ig Ova bara je mesto gde plovi barokna barka, kao i barža, ali samo dok je baraka zatvorena. Sada se "bara" ne uklapa, pošto zbog kvantifikatora + mora bar jedan znak da se nađe između "bar" i "a". Zato se sada uklapa "barka" i "baraka" (ima dva znaka i oba su ili "a" ili "k"). Vidimo da se "barža" i "barokna" nikako ne uklapa pošto tu znakovi između "bar" i "a" nisu isključivo "k" ili "a".
Znak se pojavljuje nijednom ili više puta bar[ka]*a ig Ova bara je mesto gde plovi barokna barka, kao i barža, ali samo dok je baraka zatvorena. U ovom slučaju je uključena i "bara", pošto kvantifikator * dozvoljava da se znak pojavi nijednom, jednom ili više puta.

Možda ste primetili da je u poslednjem primeru izabrana reč "baraka", a isto tako se uklapalo i "bara" iz te iste reči. Kako je odlučeno da se izabere duže rešenje? Razlog za ovo je što se za uparivanje po regularnim izrazima koristi tzv. pohlepni algoritam, koji suštinski znači da će se uvek tražiti poklapanje po kome je obuhvaćen maksimalan broj znakova.

Lenjo i pohlepno uparivanje

Kada zadamo neki kvantifikator koji se odnosi na "više znakova" logično je da se zapitamo koliko će zaista znakova biti obuhvaćeno. Pogledajte sledeći primer:

/a.+a/ OVO: "ana nije sama" NE OVO: "ana nije sama"

Ovaj šablon bismo mogli da prepričamo kao jedan ili više bilo kojih znakova između dva slova "a". Tako gledano, u njega bi se zaista svašta uklopilo. Minimalni slučaj je samo reč "ana" (jedan jedini znak), a maksimalni bi bio ceo tekst od prvog do poslednjeg "a".

Rezultat uparivanja će zavisiti od toga koji algoritam koristi "mašina" koja izvršava regularni izraz. Po defaultu se koristi tzv. pohlepni (greedy) algoritam, što znači da će po regularnom izrazu poklapanje obuhvatiti maksimalno moguć broj znakova.

Ako nam ovo ne odgovara, alternativa je lenjo (lazy) uparivanje, kada se uzima najmanji mogući broj znakova koji se uklapa u šablon.

Ako želimo da se koristi lenjo uparivanje, moramo da "modifikujemo" kvantifikator, odnosno da posle njega dodamo znak pitanja - ?. Tako ovaj specijalni znak ima dvostruku funkciju, zavisno da li se zadaje posle nekog znaka (kvantifikator) ili posle kvantifikatora * i + kada služi za korišćenje lenjog uparivanja.

/a.+?a/ OVO: "ana nije sama" NE OVO: "ana nije sama"

Isprobajte i sami na nekom od primera:

Bilo koji znak nijednom ili više puta - pohlepno uparivanje bar.*a ig Ova bara je mesto gde plovi barokna barka, kao i barža, ali samo dok je baraka zatvorena. Dakle ovo je šablon koji obuhvata bilo koji broj, bilo kojih znakova između "bar" i "a". Pošto se koristi pohlepno uparivanje, znači da će uvek biti prihvaćeno najduže moguće rešenje - počev od prve pojave teksta "bar", pa do poslednje pojave teksta "a".
Bilo koji znak nijednom ili više puta - lenjo uparivanje bar.*?a ig Ova bara je mesto gde plovi barokna barka, kao i barža, ali samo dok je baraka zatvorena. Sada ćemo "modifikovati" kvantifikator *, korišćenjem znaka ?. Ovo znači da će se koristiti lenjo uparivanje, odnosno da će svako rešenje biti najkraće moguće. Pošto sada znakovi između "bar" i "a" mogu i ne moraju da se pojavljuju (*), pronađen je i tekst "bara", kao i sve moguće varijante između svake pojave "bar" i "a".
Bilo koji znak jednom ili više puta - lenjo uparivanje bar.+?a ig Ova bara je mesto gde plovi barokna barka, kao i barža, ali samo dok je baraka zatvorena. Mala razlika nastaje kada koristimo kvantifikator + koji zahteva da se između "bar" i "a" nađe makar jedan znak. Primećujete da sada tekst "bara" ne uklapa, pa je obuhvaćeno više znakova do prve sledeće pojave znaka "a".

Tačno određen broj ponavljanja

Kao da sve ovo nije bilo dosta, moguće je zadati i tačno koliko puta se zahteva da se neki znak ponovi. Da bismo tačno definisali broj ponavljanja, koristimo vitičaste zagrade {...}. Postoje sledeće mogućnosti:

Z{N} zadati znak se mora pojaviti tačno N puta
Z{N,M} zadati znak se može pojaviti najmanje N a najviše M puta
Z{N,M}? zadati znak se može pojaviti najmanje N a najviše M puta uz lenjo uparivanje
Z{N,} zadati znak se mora pojaviti najmanje N puta
Z{N,}? zadati znak se mora pojaviti najmanje N puta uz lenjo uparivanje

Pogledajmo kako ovo funkcioniše na primerima.

Bilo koji znak tačno 3 puta bar.{3}a ig Ova bara je mesto gde plovi barokna barka, kao i barža, ali samo dok je baraka zatvorena. Dakle ovo je šablon koji obuhvata tačno 3 bilo koja znaka između "bar" i "a".
Bilo koji znak bar 2 puta - pohlepno uparivanje bar.{2,}a ig Ova bara je mesto gde plovi barokna barka, kao i barža, ali samo dok je baraka zatvorena. U ovako zadatom šablonu traže se najmanje 2 bilo koja znaka između "bar" i "a". Obuhvaćen je veliki deo teksta, zato što se koristi pohlepno uparivanje.
Bilo koji znak bar 2 puta - lenjo uparivanje bar.{2,}?a ig Ova bara je mesto gde plovi barokna barka, kao i barža, ali samo dok je baraka zatvorena. Ovo je isti šablon kao malopre (koji obuhvata najmanje 2 bilo koja znaka između "bar" i "a"). Za razliku od prethodnog primera, upotrebili smo i znak pitanja ?, kako bismo forsirali lenjo uparivanje.
Bilo koji znak 2 do 4 puta - pohlepno uparivanje bar.{2,4}a ig Ova bara je mesto gde plovi barokna barka, kao i barža, ali samo dok je baraka zatvorena. A svi viču "Pazi baraaaaaaaa"! Hajde još da isprobamo šablon u kome zahtevamo od 2 do 4 bilo koja znaka između "bar" i "a". Obratite pažnju na poslednju pronađenu reč (uzvik "baraaaaaaaa") - u šablon se uklapaju i "baraaa" i "baraaaa" i "baraaaaa", a selektovana je poslednja varijanta, pogađate, zbog pohlepnog uparivanja.
Bilo koji znak 2 do 4 puta - lenjo uparivanje bar.{2,4}?a ig Ova bara je mesto gde plovi barokna barka, kao i barža, ali samo dok je baraka zatvorena. A svi viču "Pazi baraaaaaaaa"! U ovom primeru je sve isto kao malopre, s tim što koristimo lenjo uparivanje (dodali smo znak pitanja ? posle kvantifikatora). Vidimo razliku u poslednjoj reči, kada je selektovana najkraća moguća varijanta (samo dva znaka "a" između "bar" i "a").
  1. A. Watt (2005): Beginning Regular Expressions, Wiley Publishing, Indianapolis
  2. J. Goyvaerts, S. Levithan (2012): Regular Expressions Cookbook, 2nd Ed, O’Reilly, Sebastopol
Svi elementi sajta Web'n'Study, osim onih za koje je navedeno da su u javnom vlasništvu, vlasništvo su autora i ne smeju se koristiti, u celosti ili delimično bez pismenog odobrenja autora. To uključuje tekstove, slike, ilustracije, animacije, prateći grafički materijal i programski kod.
Ovaj sajt koristi tehnologiju kolačića (cookies). Detaljnije o tome možete pročitati u tekstu o našoj politici privatnosti.