MySQL Reguláris kifejezések (Regexp)

⚡ Okos összefoglaló

MySQL A reguláris kifejezések (REGEXP) az oszlopértékeket olyan rugalmas mintákkal egyeztetik, amelyeket a helyettesítő karakterek nem tudnak kifejezni. Ez elmagyarázza a REGEXP szintaxisát, az RLIKE szinonimát, az összes támogatott metakaraktert, a myflixdb adatbázissal szemben javított lekérdezési példákat, valamint a hozzáadott reguláris kifejezésfüggvényeket. MySQL 8.0.

  • 🔍 Mag Operator: A REGEXP egy oszlopot hasonlít össze egy mintával, és 1-et ad vissza egyezés esetén, míg az RLIKE a REGEXP pontos szinonimája.
  • 🧩 Mintás Anchors: A kalapjel (^) az érték elejéhez, a dollárjel ($) pedig a végéhez rögzíti az egyezést.
  • 🔤 Karakterlisták: Az [abcd] bármely bekeretezett karakterre illeszkedik, az [^abcd] pedig minden bekeretezett karaktert kizár az eredményhalmazból.
  • Mennyiségi jelzők: A csillag, a pluszjel és a kérdőjel az előttük lévő egyetlen karakterre vonatkozik, nem az egész karakterláncra.
  • 🛡️ Escaping Szabály: Egy literális fordított perjelet meg kell duplázni egy mintán belül, mert MySQL kétszer dolgozza fel a karakterláncot.
  • 🆕 Verzióváltás: MySQL A 8.0-s verzió átkerült az ICU motorba, a [[:<:]] és [[:>:]] helyét \b karakterre cserélte, valamint hozzáadta a REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR és REGEXP_INSTR értékeket.
  • Teljesítmény megjegyzés: A REGEXP soha nem használ indexet, ezért először indexelt feltétellel szűrjük a sorokat, amikor a lekérdezés ezt lehetővé teszi.

Mik MySQL reguláris kifejezések?

MySQL szabályos kifejezések segítenek az összetett kritériumoknak megfelelő adatok keresésében. A reguláris kifejezés egy minta, amely a keresett érték alakját írja le, nem pedig magát az értéket.

Ha már dolgoztál együtt MySQL helyettesítő karakterek, felmerülhet a kérdés, hogy miért érdemes megtanulni a reguláris kifejezéseket, amikor a LIKE hasonló eredményeket produkál. A válasz a kifejezőerőben rejlik: a helyettesítő karakterek csak két szimbólumot kínálnak, míg a reguláris kifejezések egyetlen mintában írják le a karaktertartományokat, az alternatívákat, az ismétlődéseket és a szópozíciókat.

Miután a célt meghatároztuk, a következő szakasz bemutatja a szintaxist, amelyet minden REGEXP lekérdezésben használni fogunk.

A REGEXP alapvető szintaxisa

A reguláris kifejezés alapvető szintaxisa a következő.

SELECT * FROM table_name
WHERE fieldname REGEXP 'pattern';

ITT:

  • „SELECT utasítás” a szabvány SELECT utasítás.
  • „WHERE mezőnév” annak az oszlopnak a neve, amelyen a reguláris kifejezés végrehajtásra kerül.
  • „REGEXP 'minta'” — A REGEXP a reguláris kifejezés operátora, a „pattern” pedig az egyeztetendő mintát jelöli. RLIKE egy olyan a REGEXP szinonimája és ugyanazt az eredményt adja vissza. A LIKE operátorral való összetévesztés elkerülése érdekében jobb, ha a REGEXP operátort használjuk.

Most nézzünk egy gyakorlati példát.

SELECT * FROM `movies`
WHERE `title` REGEXP 'code';

A fenti lekérdezés az összes olyan filmcímet keresi, amely tartalmazza a „kód” szót. Nem számít, hogy a „kód” a cím elején, közepén vagy végén szerepel-e. Amíg a cím tartalmazza a mintát, a sort adja vissza.

Érték kezdetének egyeztetése egy karakterlistával

Tegyük fel, hogy olyan filmeket keresünk, amelyek címe a, b, c vagy d betűvel kezdődik, majd tetszőleges számú további karakter következik. Egy karakterlistát kombinálunk a kalap metakarakterrel, hogy elérjük ezt az eredményt.

SELECT * FROM `movies`
WHERE `title` REGEXP '^[abcd]';

A fenti szkript végrehajtása MySQL Workbench a myflixdb adatbázissal szemben a következő eredményeket kapjuk.

film_id cím rendező év_megjelent kategória_azonosítója
4 Code Név Fekete Edgar Jimz 2010 NULL
5 Apa kislányai NULL 2007 8
6 angyalok és démonok NULL 2007 6
7 davinci Code NULL 2007 6

A '^[abcd]' mintában a kalap (^) megköveteli, hogy az egyezés az érték elején kezdődjön, és az [abcd] karakterlista csak azokat a címeket fogadja el, amelyek első betűje a, b, c vagy d. Az összehasonlítás az alapértelmezett rendezés mellett nem megkülönbözteti a kis- és nagybetűket, ezért „Code A „Név Fekete” kifejezést adja vissza a rendszer.

Negált karakterlistával rendelkező karakterek kizárása

Módosítsuk most a szkriptet, és negáljuk a karakterlistát, hogy lássuk, mely sorokat adja vissza.

SELECT * FROM `movies`
WHERE `title` REGEXP '^[^abcd]';

A fenti szkript végrehajtása MySQL A Workbench és a myflixdb adatbázis összehasonlítása a következő eredményeket adja.

film_id cím rendező év_megjelent kategória_azonosítója
1 A Karib-tenger kalózai 4 Rob Marshall 2011 1
2 Sarah Marshal elfelejtése Nicholas stoller 2008 2
3 X-Men 2008
9 Honey moonERS Schultz János 2005 8
16 67% bűnös 2012
17 A diktátor Chalie Chaplie 1920 7
18 mintafilm Névtelenül 8
19 3. film John Brown 1920 8

Egy karakterlistán belül a kurzor jelentése megváltozik: a '^[^abcd]' továbbra is az elejére helyezi a találatot, míg az [^abcd] mostantól kizár minden olyan címet, amely a benne foglalt karakterek egyikével kezdődik.

Ez a két példa csak horgonyokat és karakterlistákat használ. A következő szakasz a teljes metakarakterkészletet tárgyalja.

Reguláris kifejezés metakarakterei

A fenti példák a reguláris kifejezések legegyszerűbb formáját mutatják. A metakarakterek lehetővé teszik a mintakeresés finomhangolását: ismétlést, alternatívákat, tartományokat és pozíciókat fejeznek ki. Az alábbi táblázat felsorolja a reguláris kifejezés által támogatott összes metakaraktert. MySQL REGEXP operátor, mindegyikhez egy javított példával.

Faszén Leírás Példa
* Az csillag (*) nulla (0) vagy több előfordulással egyezik a egyetlen karakter ami megelőzi azt. SELECT * FROM filmek WHERE cím REGEXP 'da*'; egy „d” betűt, majd nulla vagy több „a” karaktert talál, tehát a Da Vinci Code és az Apuci kicsi lányai is megfelelnek a feltételeknek. Használj 'da+'-t, ha az „a” betűnek szerepelnie kell.
+ Az plusz (+) egy vagy több előfordulással egyezik az azt megelőző karakterrel. SELECT * FROM `filmek` WHERE `cím` REGEXP 'h+'; az összes olyan filmet adja vissza, amely tartalmazza a „mon” karaktert, majd egy vagy több „n” karaktert. Például: Angyalok és démonok.
? Az kérdőjel (?) nullára (0) vagy az azt megelőző karakter egyetlen előfordulására illeszkedik. SELECT * FROM `categories` WHERE `kategória_neve` REGEXP 'com?'; egyezik a „co” betűvel és egy opcionális „m” betűvel. Például: vígjáték és romantikus vígjáték.
. Az pont (.) bármely karakterrel egyezik, kivéve az új sort. SELECT * FROM filmek WHERE `year_released` REGEXP '200.'; egy adott évben megjelent összes filmet megadja „200”-zal kezdődően, amelyet egyetlen karakter követ. Például: 2005, 2007, 2008.
[ABC] Az karakterlista [abc] egyezik a mellékelt karakterek bármelyikével. SELECT * FROM `filmek` WHERE `cím` REGEXP '[vwxyz]'; minden olyan filmet megad, amelyben a „vwxyz” szó bármelyik szereplője szerepel. Például: X-Men és Da Vinci Code.
[^abc] Az negált lista [^abc] bármely karakterrel egyezik, kivéve a bekeretezetteket. SELECT * FROM `filmek` WHERE `cím` REGEXP '^[^vwxyz]'; minden olyan filmet megad, amelynek a címe nem a „vwxyz” karakterével kezdődik.
[AZ] Az tartomány [AZ] bármely nagybetűvel egyezik. SELECT * FROM `tagok` WHERE `postai_cím` REGEXP '[AZ]'; minden olyan tagot megad, akinek a postai címe A és Z közötti betűt tartalmaz. Például Janet Jones, akinek a tagsági száma 1.
[az] Az tartomány [az] bármely kisbetűvel egyezik. SELECT * FROM `tagok` WHERE `postai_cím` REGEXP '[az]'; minden olyan tagot megad, akinek a postai címe a és z közötti betűt tartalmaz. Vegye figyelembe, hogy az alapértelmezett rendezés nem megkülönbözteti a kis- és nagybetűket, így ez a tartomány a nagybetűket is figyelembe veszi.
[0-9] Az tartomány [0-9] 0 és 9 közötti bármely számjegyre illeszkedik. SELECT * FROM `tagok` WHERE `kapcsolati_szám` REGEXP '[0-9]'; minden olyan tagot megad, akinek az elérhetősége legalább egy számjegyet tartalmaz. Például: Robert Phil.
^ Az törpe (^) az egyezést az érték elejéhez rögzíti. SELECT * FROM `filmek` WHERE `cím` REGEXP '^[cd]'; minden olyan filmet megad, amelynek a címe „c” vagy „d” betűvel kezdődik. Például Code Név Black, Apuci kislányai és Da Vinci Code.
$ Az dollárjel ($) az egyezést az érték végéhez rögzíti. SELECT * FROM `filmek` WHERE `cím` REGEXP 'kód$'; minden olyan filmet megad, amelynek a címe „kód”-ra végződik. Például: Davinci Code.
| Az függőleges sáv (|) alternatívákat izolál. SELECT * FROM `filmek` WHERE `cím` REGEXP '^[cd]|^[u]'; minden olyan filmet megad, amelynek címe „c”, „d” vagy „u” betűvel kezdődik. Például Code Név: Black, Da Vinci Code, és az Alvilág – AwakenIng.
\b Az szóhatár (\b) egy szó elejére vagy végére illeszkedik. Lecseréli a régebbi [[:<:]] és [[:>:]] jelölőket, amelyek MySQL 8.0 eltávolítva. SELECT * FROM `filmek` WHERE `cím` REGEXP '\\bfor'; minden olyan filmet megad, amelynek a szója „for”-ral kezdődik. Például: Forgetting Sarah Marshal. MySQL 5.7-es verzióban az ezzel ekvivalens minta a '[[:<:]]for'.
[[:osztály:]] Az karakter osztály egy elnevezett karaktercsoportra illeszkedik: [[:alpha:]] betűk, [[:space:]] szóközök, [[:punct:]] írásjelek és [[:upper:]] nagybetűk esetén. Figyeljük meg a következőt: kétszeresére szögletes zárójelek. SELECT * FROM `filmek` WHERE `cím` REGEXP '^[[:alpha:][:space:]]+$'; az összes olyan filmet megadja, amelynek címe csak betűket és szóközöket tartalmaz. Például: Forgetting Sarah Marshal, míg a Pirates of the Caribbean 4 a számjegy miatt kimarad.

A fordított perjel (\) az escape karakter. Mivel MySQL először a karakterláncot, majd csak másodszor a mintát elemzi, a literális fordított perjelet dupla fordított perjelként (\\) kell írni egy REGEXP mintán belül.

⚠️ Verzió figyelmeztetés: MySQL A 8.0.4-es verzióban a régi reguláris kifejezésmotort az ICU könyvtár váltotta fel. A [[:<:]] és [[:>:]] szójelölőket eltávolították ebben a kiadásban, így a régebbi anyagokból másolt minták „szintaktikai hibával” hibát jeleznek a következőn: MySQL 8.0. Használd helyette a \b karakterláncot.

Most, hogy minden metakarakter definiálva van, jogos kérdés merül fel: mikor kell a REGEXP-nek lecserélnie az egyszerűbb LIKE operátort?

REGEXP vs. LIKE: melyiket érdemes használni?

Mindkét operátor minta alapján szűri a sorokat, de különböző problémákat oldanak meg. A LIKE csak két szimbólumot ért, míg a REGEXP a fent látható teljes metakarakterkészletet. Ennek a képességnek ára van, így a választás inkább kompromisszum, mint preferencia kérdése.

Kritérium HASONLÓ REGULÁRIS KIFEJEZÉS
Minta szimbólumok Csak % és _ Anchors, tartományok, alternáció, kvantorok, karakterosztályok
Tipikus felhasználás Előtag, utótag és „tartalmaz” keresések Validáció, több alternatíva, pozíciófüggő párosítás
Indexhasználat Lehetséges, ha a minta nem % karakterrel kezdődik Soha nem használ indexet
Visszatérési érték IGAZ vagy HAMIS 1 vagy 0, és NULL, ha bármelyik operandus NULL

Az egyszerű egyezéshez válaszd a LIKE kifejezést, mert jól olvasható és továbbra is használhat indexet. A REGEXP kifejezést akkor válaszd, ha egyetlen mintának egyszerre több szabályt kell kifejeznie, például „c-vel vagy d-vel kezdődik és számjeggyel végződik”. Nagy táblázatokban először szűkítsd a sorokat egy indexelt feltétellel, majd alkalmazd a REGEXP kifejezést erre a kisebb halmazra.

MySQL 8.0 reguláris kifejezésfüggvények

A REGEXP operátor csak egy kérdésre válaszol: illeszkedik-e az érték a mintához? MySQL A 8.0 négy olyan funkciót adott hozzá, amelyek továbbmennek, és lehetővé teszik a keresést, pl.tract, és írd át az egyező szöveget. Mindegyik elfogad egy opcionális match_type argumentumot, ahol a 'c' kis- és nagybetűérzékeny összehasonlítást, az 'i' pedig nem megkülönböztető összehasonlítást tesz szükségessé.

  • REGEXP_LIKE(kifejezés, minta) 1-et ad vissza, ha az érték megegyezik a mintával. Ez a REGEXP operátor függvényformája, és a match_type argumentum explicit módon megkülönbözteti a kis- és nagybetűket.
  • REGEXP_INSTR(kifejezés, minta) visszaadja az egyezés első karakterének pozícióját, vagy 0-t, ha a minta nem található.
  • REGEXP_SUBSTR(kifejezés, minta) magát a megfelelő részkarakterláncot adja vissza, ami hasznos egy év, egy kód vagy egy szám kinyerésére egy hosszabb szöveges értékből.
  • REGEXP_REPLACE(kifejezés, minta, csere) minden egyes egyezést kicserélve visszaadja az értéket, így tisztíthatja az adatokat egy SQL UPDATE lekérdezés.
SELECT title,
       REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title
FROM `movies`
WHERE REGEXP_LIKE(title, '[0-9]');

A fenti lekérdezés minden olyan filmcímet visszaad, amely tartalmaz egy számjegyet, magukkal a számjegyekkel együtt. MySQL 5.7-ben ezek a függvények nem érhetők el, így a REGEXP operátor marad az egyetlen lehetőség.

GYIK

Alapértelmezés szerint nem. A REGEXP az oszlop rendezését követi, és a szabványos rendezések nem megkülönböztetik a kis- és nagybetűket. Adja hozzá a BINARY kulcsszót az oszlop elé, vagy hívja meg a REGEXP_LIKE függvényt 'c' egyezési típussal, hogy kis- és nagybetűérzékeny összehasonlítást kényszerítsen ki.

Nincs funkcionális különbség. Az RLIKE a REGEXP szinonimája, amely MySQL kompatibilitási okokból megtartjuk. A gyakorlatban a REGEXP-et részesítjük előnyben, mivel az RLIKE könnyen összetéveszthető a nem kapcsolódó LIKE operátor helyettesítő karakterekhez használják.

A REGEXP nem használhat indexet, tehát MySQL soronként kiértékeli a mintát. Először csökkentse a beolvasott sorok számát egy indexelt feltétellel, egy dátumtartománnyal vagy egy teljes szöveges indexszel, majd alkalmazza a reguláris kifejezést erre a kisebb eredményhalmazra.

Igen. A mesterséges intelligencia asszisztensek egy egyszerű nyelvi szabályt REGEXP mintává alakítanak, és elmagyarázzák az egyes metakaraktereket. Teszteld az eredményt a következőben: MySQL Workbench a minta sorokkal szemben, mivel egyetlen rosszul elhelyezett horgony megváltoztatja a teljes eredményhalmazt.

Igen. A mesterséges intelligencia asszisztensek REGEXP_REPLACE utasításokat generálnak, amelyek eltávolítják az írásjeleket, normalizálják a telefonszámokat vagy kivágják a szóközöket. Először futtassa a mintát egy SELECT-en belül, erősítse meg az átírt értékeket, és csak ezután alkalmazza egy... UPDATE nyilatkozat.

Foglald össze ezt a bejegyzést a következőképpen: