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.
