MySQL Regularni izrazi (Regexp)
โก Pametni saลพetak
MySQL Regularni izrazi (REGEXP) usporeฤuju vrijednosti stupaca s fleksibilnim obrascima koje zamjenski znakovi ne mogu izraziti. Ovo objaลกnjava sintaksu REGEXP-a, sinonim RLIKE, svaki podrลพani metaznak, ispravljene primjere upita u bazi podataka myflixdb i funkcije regularnih izraza dodane u MySQL 8.0.

ล to su MySQL regularni izrazi?
MySQL pravilni izrazi pomoฤi ฤe vam u pretraลพivanju podataka koji odgovaraju sloลพenim kriterijima. Regularni izraz je uzorak koji opisuje oblik vrijednosti koju traลพite, a ne samu vrijednost.
Ako ste veฤ radili s MySQL zamjenski znakovi, moลพda se pitate zaลกto se isplati uฤiti regularne izraze kada LIKE daje sliฤne rezultate. Odgovor je ekspresivna moฤ: zamjenski znakovi nude samo dva simbola, dok regularni izrazi opisuju raspone znakova, alternative, ponavljanje i pozicije rijeฤi u jednom uzorku.
Nakon ลกto je svrha utvrฤena, sljedeฤi odjeljak predstavlja sintaksu koju ฤete koristiti u svakom REGEXP upitu.
Osnovna sintaksa REGEXP-a
Osnovna sintaksa regularnog izraza je sljedeฤa.
SELECT * FROM table_name WHERE fieldname REGEXP 'pattern';
OVDJE:
- "SELECT izjava" je standard SELECT izraz.
- "WHERE naziv polja" je naziv stupca na kojem se izvrลกava regularni izraz.
- โREGEXP 'uzorak'โ โ REGEXP je operator regularnog izraza, a 'pattern' predstavlja uzorak koji treba pronaฤi. RLIKE je sinonim za REGEXP i vraฤa iste rezultate. Kako biste izbjegli mijeลกanje s operatorom LIKE, bolje je koristiti REGEXP.
Pogledajmo sada praktiฤan primjer.
SELECT * FROM `movies` WHERE `title` REGEXP 'code';
Gornji upit traลพi sve naslove filmova koji sadrลพe rijeฤ "code". Nije vaลพno pojavljuje li se "code" na poฤetku, u sredini ili na kraju naslova. Vraฤa se redak sve dok naslov sadrลพi uzorak.
Usklaฤivanje poฤetka vrijednosti s popisom znakova
Pretpostavimo da ลพelimo filmove ฤiji naslovi poฤinju s a, b, c ili d, nakon ฤega slijedi bilo koji broj drugih znakova. Kombiniramo popis znakova s โโmetaznakom karet kako bismo postigli taj rezultat.
SELECT * FROM `movies` WHERE `title` REGEXP '^[abcd]';
Izvrลกavanje gornje skripte u MySQL Radna tezga u odnosu na bazu podataka myflixdb daje nam sljedeฤe rezultate.
| film_id | naslov | direktor | godina_izdana | kategorija_id |
|---|---|---|---|---|
| 4 | Code Ime Crno | Edgar Jimz | 2010 | NULL |
| 5 | Tatine djevojฤice | NULL | 2007 | 8 |
| 6 | Anฤeli i demoni | NULL | 2007 | 6 |
| 7 | Da Vinci Code | NULL | 2007 | 6 |
U uzorku '^[abcd]', znak za umetanje (^) zahtijeva da podudaranje poฤinje na poฤetku vrijednosti, a popis znakova [abcd] prihvaฤa samo naslove ฤije je prvo slovo a, b, c ili d. Usporedba nije osjetljiva na velika i mala slova pod zadanim sortiranjem, zbog ฤega โCode Vraฤa se "Name Black".
Iskljuฤivanje znakova s โโpopisa negiranih znakova
Sada modificirajmo skriptu i negirajmo popis znakova kako bismo vidjeli koji se retci vraฤaju.
SELECT * FROM `movies` WHERE `title` REGEXP '^[^abcd]';
Izvrลกavanje gornje skripte u MySQL Workbench na bazi podataka myflixdb daje nam sljedeฤe rezultate.
| film_id | naslov | direktor | godina_izdana | kategorija_id |
|---|---|---|---|---|
| 1 | Pirati s Kariba 4 | Rob Marshall | 2011 | 1 |
| 2 | Zaboravljam Saru Marshal | Nicholas stoller | 2008 | 2 |
| 3 | X-Men | 2008 | ||
| 9 | Honey moonERS | John Schultz | 2005 | 8 |
| 16 | 67% kriv | 2012 | ||
| 17 | Veliki diktator | Chalie Chaplie | 1920 | 7 |
| 18 | primjer filma | anoniman | 8 | |
| 19 | film 3 | John Brown | 1920 | 8 |
Unutar popisa znakova, znak umetanja mijenja znaฤenje: '^[^abcd]' i dalje usidrava podudaranje na poฤetku, dok [^abcd] sada iskljuฤuje svaki naslov koji poฤinje jednim od zatvorenih znakova.
Ova dva primjera koriste samo sidra i popise znakova. Sljedeฤi odjeljak pokriva cijeli skup metaznakova.
Metaznakovi regularnog izraza
Gornji primjeri prikazuju najjednostavniji oblik regularnog izraza. Metaznakovi vam omoguฤuju fino podeลกavanje pretraลพivanja uzorka: izraลพavaju ponavljanje, alternative, raspone i pozicije. Tablica u nastavku navodi svaki metaznak koji podrลพava MySQL REGEXP operator, s ispravljenim primjerom za svaki od njih.
| Char | Description | Primjer | |
|---|---|---|---|
| * | The zvjezdica (*) odgovara nula (0) ili viลกe instanci od jedan znak koji tome prethodi. | SELECT * FROM movies WHERE naslov REGEXP 'da*'; odgovara slovu "d" nakon kojeg slijedi nula ili viลกe znakova "a", dakle Da Vinci Code i Daddy's Little Girls se kvalificiraju. Koristite 'da+' kada slovo "a" mora biti prisutno. | |
| + | The viลกe (+) odgovara jednoj ili viลกe instanci znaka koji mu prethodi. | SELECT * FROM `filmovi` WHERE `naslov` REGEXP 'pon+'; vraฤa sve filmove koji sadrลพe "mon" nakon ฤega slijedi jedan ili viลกe znakova "n". Na primjer, Anฤeli i demoni. | |
| ? | The upitnik (?) odgovara nula (0) ili jednoj instanci znaka koji mu prethodi. | SELECT * FROM `categories` WHERE `category_name` REGEXP 'com?'; "co" se podudara s neobaveznim "m". Na primjer, komedija i romantiฤna komedija. | |
| . | The toฤka (.) odgovara bilo kojem pojedinaฤnom znaku osim novog retka. | SELECT * FROM movies WHERE `year_released` REGEXP '200.'; prikazuje sve filmove objavljene u godini poฤevลกi s "200" nakon ฤega slijedi bilo koji pojedinaฤni znak. Na primjer, 2005, 2007, 2008. | |
| [abc] | The popis znakova [abc] odgovara bilo kojem od zatvorenih znakova. | SELECT * FROM `filmovi` WHERE `naslov` REGEXP '[vwxyz]'; prikazuje sve filmove koji sadrลพe bilo kojeg lika iz "vwxyz". Na primjer X-Men i Da Vinci Code. | |
| [^abc] | The negirani popis [^abc] odgovara bilo kojem znaku osim onih u zatvorenom. | SELECT * FROM `filmovi` WHERE `naslov` REGEXP '^[^vwxyz]'; prikazuje sve filmove ฤiji naslov ne poฤinje znakom u "vwxyz". | |
| [AZ] | The raspon [AZ] odgovara bilo kojem velikom slovu. | SELECT * FROM `ฤlanovi` WHERE `poลกtanska_adresa` REGEXP '[AZ]'; prikazuje sve ฤlanove ฤija poลกtanska adresa sadrลพi slovo izmeฤu A i Z. Na primjer, Janet Jones s ฤlanskim brojem 1. | |
| [the] | The raspon [az] odgovara bilo kojem malom slovu. | SELECT * FROM `ฤlanovi` WHERE `poลกtanska_adresa` REGEXP '[az]'; daje sve ฤlanove ฤija poลกtanska adresa sadrลพi slovo izmeฤu a i z. Imajte na umu da zadana sortacija nije osjetljiva na velika i mala slova, pa ovaj raspon takoฤer odgovara velikim slovima. | |
| [0-9] | The raspon [0-9] odgovara bilo kojoj znamenki od 0 do 9. | SELECT * FROM `ฤlanovi` WHERE `kontaktni_broj` REGEXP '[0-9]'; daje sve ฤlanove ฤiji kontaktni broj sadrลพi barem jednu znamenku. Na primjer, Robert Phil. | |
| ^ | The znak za umetanje (^) usidrava podudaranje na poฤetak vrijednosti. | SELECT * FROM `filmovi` WHERE `naslov` REGEXP '^[cd]'; prikazuje sve filmove ฤiji naslov poฤinje s "c" ili "d". Na primjer Code Ime Black, Tatine male djevojฤice i Da Vinci Code. | |
| $ | The znak dolara ($) usidrava podudaranje na kraj vrijednosti. | SELECT * FROM `filmovi` WHERE `naslov` REGEXP 'kod$'; prikazuje sve filmove ฤiji naslov zavrลกava s "kod". Na primjer, Da Vinci Code. | |
| | | The okomita crta (|) izolira alternative. | SELECT * FROM `filmovi` WHERE `naslov` REGEXP '^[cd]|^[u]'; prikazuje sve filmove ฤiji naslov poฤinje s "c", "d" ili "u". Na primjer Code Ime Black, Da Vinci Codei Podzemlje โ Awakening.. | |
| \b | The granica rijeฤi (\b) odgovara poฤetku ili kraju rijeฤi. Zamjenjuje starije markere [[:<:]] i [[:>:]], koji MySQL 8.0 uklonjeno. | SELECT * FROM `filmovi` WHERE `naslov` REGEXP '\\bfor'; navodi sve filmove ฤija rijeฤ poฤinje s "za". Na primjer, Zaboravljajuฤi Sarah Marshal. Na MySQL 5.7 ekvivalentni uzorak je '[[:<:]]za'. | |
| [[:razred:]] | The klasa karaktera odgovara imenovanoj skupini znakova: [[:alpha:]] za slova, [[:space:]] za razmake, [[:punct:]] za interpunkcijske znakove i [[:upper:]] za velika slova. Imajte na umu dvostruko uglate zagrade. | SELECT * FROM `filmovi` WHERE `naslov` REGEXP '^[[:alpha:][:space:]]+$'; daje sve filmove ฤiji naslov sadrลพi samo slova i razmake. Na primjer, Zaboravljajuฤi Sarah Marshal, dok je Pirati s Kariba 4 izostavljen zbog znamenke. | |
Obrnuta kosa crta (\) je znak za izlaz. Jer MySQL prvo parsira niz, a zatim uzorak, doslovna obrnuta kosa crta mora biti napisana kao dvostruka obrnuta kosa crta (\\) unutar REGEXP uzorka.
โ ๏ธ Upozorenje o verziji: MySQL Verzija 8.0.4 zamijenila je stari mehanizam regularnih izraza bibliotekom ICU. Oznake rijeฤi [[:<:]] i [[:>:]] uklonjene su u tom izdanju, pa uzorci kopirani iz starijeg materijala ne uspijevaju s "sintaktiฤkom pogreลกkom" na MySQL 8.0. Umjesto toga koristite \b.
Sada kada je svaki metaznak definiran, postavlja se opravdano pitanje: kada bi REGEXP trebao zamijeniti jednostavniji LIKE operator?
REGEXP vs. LIKE: koji biste trebali koristiti?
Oba operatora filtriraju retke prema uzorku, ali rjeลกavaju razliฤite probleme. LIKE razumije samo dva simbola, dok REGEXP razumije cijeli skup metaznakova prikazan gore. Ta moฤ ima svoju cijenu, pa je izbor kompromis, a ne preferencija.
| Kriterij | LIKE | REGEXP |
|---|---|---|
| Simboli uzoraka | samo % i _ | Anchors, rasponi, alternacija, kvantifikatori, klase znakova |
| Tipiฤna upotreba | Pretrage prefiksa, sufiksa i "sadrลพi" | Validacija, viลกe alternativa, usklaฤivanje na temelju pozicije |
| Koriลกtenje indeksa | Moguฤe kada uzorak ne poฤinje s % | Nikad ne koristi indeks |
| Povratna vrijednost | TOฤNO ili NETOฤNO | 1 ili 0, i NULL kada je bilo koji operand NULL |
Odaberite LIKE za jednostavno podudaranje, jer se dobro ฤita i joลก uvijek moลพe koristiti indeks. Odaberite REGEXP kada jedan uzorak mora izraziti nekoliko pravila odjednom, kao ลกto je โpoฤinje s c ili d i zavrลกava znamenkomโ. U velikim tablicama prvo suzite retke indeksiranim uvjetom, a zatim primijenite REGEXP na taj manji skup.
MySQL 8.0 funkcije regularnih izraza
Operator REGEXP odgovara samo na jedno pitanje: odgovara li vrijednost uzorku? MySQL Verzija 8.0 dodala je ฤetiri funkcije koje idu dalje i omoguฤuju vam lociranje, npr.tract i prepiลกite odgovarajuฤi tekst. Svaki prihvaฤa opcionalni argument match_type, gdje 'c' nameฤe usporedbu koja razlikuje velika i mala slova, a 'i' nameฤe usporedbu koja ne razlikuje velika i mala slova.
- REGEXP_LIKE(izraz, uzorak) vraฤa 1 kada vrijednost odgovara uzorku. To je funkcijski oblik operatora REGEXP, a argument match_type eksplicitno odreฤuje osjetljivost na velika i mala slova.
- REGEXP_INSTR(izraz, uzorak) vraฤa poziciju prvog znaka podudaranja ili 0 kada uzorak nije pronaฤen.
- REGEXP_SUBSTR(izraz, uzorak) vraฤa sam odgovarajuฤi podniz, ลกto je korisno za izvlaฤenje godine, koda ili broja iz duลพe tekstualne vrijednosti.
- REGEXP_REPLACE(izraz, uzorak, zamjena) vraฤa vrijednost sa svakim zamijenjenim podudaranjem, tako da moลพe oฤistiti podatke unutar SQL upit za aลพuriranje.
SELECT title, REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title FROM `movies` WHERE REGEXP_LIKE(title, '[0-9]');
Gornji upit vraฤa svaki naslov filma koji sadrลพi znamenku, zajedno sa samim znamenkama. MySQL 5.7 ove funkcije nisu dostupne, pa operator REGEXP ostaje jedina opcija.
