MySQL Regulære uttrykk (Regexp)
⚡ Smart oppsummering
MySQL Regulære uttrykk (REGEXP) matcher kolonneverdier mot fleksible mønstre som jokertegn ikke kan uttrykke. Dette forklarer REGEXP-syntaks, RLIKE-synonymet, alle støttede metategn, korrigerte spørreeksempler mot myflixdb-databasen og de regulære uttrykksfunksjonene som er lagt til i MySQL 8.0.

Hva er MySQL regulære uttrykk?
MySQL vanlig uttrykk hjelpe deg med å søke etter data som samsvarer med komplekse kriterier. Et regulært uttrykk er et mønster som beskriver formen på verdien du leter etter, snarere enn selve verdien.
Hvis du allerede har jobbet med MySQL jokertegn, lurer du kanskje på hvorfor det er verdt å lære seg regulære uttrykk når LIKE gir lignende resultater. Svaret er uttrykkskraft: jokertegn tilbyr bare to symboler, mens regulære uttrykk beskriver tegnområder, alternativer, repetisjon og ordposisjoner i et enkelt mønster.
Med formålet etablert, introduserer neste avsnitt syntaksen du vil bruke i hver REGEXP-spørring.
Grunnleggende syntaks for REGEXP
Den grunnleggende syntaksen for et regulært uttrykk er som følger.
SELECT * FROM table_name WHERE fieldname REGEXP 'pattern';
HER:
- «SELECT-setning» er standarden SELECT-setning.
- "HVOR feltnavn" er navnet på kolonnen som det regulære uttrykket utføres på.
- "REGEXP 'mønster'" — REGEXP er operatoren for regulært uttrykk, og 'mønster' representerer mønsteret som skal matches. RLIKE er en synonym for REGEXP og returnerer de samme resultatene. For å unngå å forveksle den med LIKE-operatoren, er det bedre å bruke REGEXP.
La oss nå se på et praktisk eksempel.
SELECT * FROM `movies` WHERE `title` REGEXP 'code';
Søket ovenfor søker etter alle filmtitler som inneholder ordet «kode». Det spiller ingen rolle om «kode» vises i begynnelsen, midten eller på slutten av tittelen. Så lenge tittelen inneholder mønsteret, returneres raden.
Samsvarer starten av en verdi med en tegnliste
Anta at vi ønsker filmene der titlene starter med a, b, c eller d, etterfulgt av et hvilket som helst antall andre tegn. Vi kombinerer en tegnliste med cirkumfleksmetategnet for å oppnå det resultatet.
SELECT * FROM `movies` WHERE `title` REGEXP '^[abcd]';
Utfører skriptet ovenfor i MySQL Workbench mot myflixdb-databasen gir oss følgende resultater.
| movie_id | tittel | direktør | år_utgitt | kategori_id |
|---|---|---|---|---|
| 4 | Code Navn Svart | Edgar Jimz | 2010 | NULL |
| 5 | Pappas småjenter | NULL | 2007 | 8 |
| 6 | engler og demoner | NULL | 2007 | 6 |
| 7 | Da Vinci Code | NULL | 2007 | 6 |
I mønsteret '^[abcd]' krever cirkumflekstegnet (^) at kampen starter i begynnelsen av verdien, og tegnlisten [abcd] godtar bare titler der den første bokstaven er a, b, c eller d. Sammenligningen skiller ikke mellom store og små bokstaver under standard sorteringen, og det er derfor “Code «Navn Svart» returneres.
Ekskludering av tegn med en negert tegnliste
La oss nå endre skriptet og negere tegnlisten for å se hvilke rader som returneres.
SELECT * FROM `movies` WHERE `title` REGEXP '^[^abcd]';
Utfører skriptet ovenfor i MySQL Arbeidsbenk mot myflixdb-databasen gir oss følgende resultater.
| movie_id | tittel | direktør | år_utgitt | kategori_id |
|---|---|---|---|---|
| 1 | Pirates of the Caribean 4 | Rob Marshall | 2011 | 1 |
| 2 | Glemte Sarah Marshal | Nicholas barnevogn | 2008 | 2 |
| 3 | X-Men | 2008 | ||
| 9 | Honey moonERS | John Schultz | 2005 | 8 |
| 16 | 67 % skyldig | 2012 | ||
| 17 | The Great Dictator | Chalie Chaplie | 1920 | 7 |
| 18 | eksempelfilm | Anonym | 8 | |
| 19 | film 3 | John Brown | 1920 | 8 |
Inne i en tegnliste endrer cirkumflekstegnet betydning: '^[^abcd]' forankrer fortsatt treffet i begynnelsen, mens [^abcd] nå ekskluderer alle titler som starter med et av de omsluttede tegnene.
Disse to eksemplene bruker bare ankere og tegnlister. Neste avsnitt dekker hele metategnsettet.
Vanlige uttrykksmetategn
Eksemplene ovenfor viser den enkleste formen for et regulært uttrykk. Metategn lar deg finjustere et mønstersøk: de uttrykker repetisjon, alternativer, områder og posisjoner. Tabellen nedenfor viser alle metategn som støttes av MySQL REGEXP-operatoren, med et korrigert eksempel for hver enkelt.
| chariot | Tekniske beskrivelser | Eksempel | |
|---|---|---|---|
| * | Ocuco stjerne (*) samsvarer med null (0) eller flere forekomster av enkeltperson som går forut for det. | VELG * FRA filmer WHERE tittel REGEXP 'da*'; samsvarer med en «d» etterfulgt av null eller flere «a»-tegn, så Da Vinci Code og Daddy's Little Girls kvalifiserer. Bruk 'da+' når bokstaven «a» faktisk må være til stede. | |
| + | Ocuco pluss (+) samsvarer med én eller flere forekomster av tegnet som kommer foran den. | VELG * FRA `movies` WHERE `title` REGEXP 'mon+'; viser alle filmer som inneholder «mon» etterfulgt av ett eller flere «n»-tegn. For eksempel Engler og demoner. | |
| ? | Ocuco spørsmålstegn (?) samsvarer med null (0) eller én forekomst av tegnet som kommer foran det. | SELECT * FRA `categories` WHERE `category_name` REGEXP 'com?'; matcher «co» med en valgfri «m». For eksempel komedie og romantisk komedie. | |
| . | Ocuco prikk (.) samsvarer med et hvilket som helst enkelttegn unntatt en ny linje. | VELG * FRA filmer WHERE `year_released` REGEXP '200.'; viser alle filmer som ble utgitt i et år, og som starter med «200» etterfulgt av en hvilken som helst karakter. For eksempel 2005, 2007, 2008. | |
| [abc] | Ocuco karakterliste [abc] samsvarer med et hvilket som helst av de omsluttede tegnene. | SELECT * FRA `movies` WHERE `title` REGEXP '[vwxyz]'; viser alle filmer som inneholder en enkelt karakter fra «vwxyz». For eksempel X-Men og Da Vinci Code. | |
| [^abc] | Ocuco negert liste [^abc] samsvarer med alle tegn unntatt de som er omsluttet. | SELECT * FRA `movies` WHERE `title` REGEXP '^[^vwxyz]'; viser alle filmer der tittelen ikke begynner med en karakter i «vwxyz». | |
| [AZ] | Ocuco rekkevidde [AZ] samsvarer med en hvilken som helst stor bokstav. | SELECT * FRA `members` WHERE `postal_address` REGEXP '[AZ]'; viser alle medlemmer hvis postadresse inneholder en bokstav mellom A og Å. For eksempel Janet Jones med medlemsnummer 1. | |
| [az] | Ocuco rekkevidde [az] samsvarer med en hvilken som helst liten bokstav. | SELECT * FRA `members` WHERE `postal_address` REGEXP '[az]'; viser alle medlemmer med en postadresse som inneholder en bokstav mellom a og z. Merk at standard sortering ikke skiller mellom store og små bokstaver, så dette området samsvarer også med store bokstaver. | |
| [0-9] | Ocuco område [0–9] samsvarer med et hvilket som helst siffer fra 0 til 9. | VELG * FRA `medlemmer` HVOR `kontaktnummer` REGEXP '[0-9]'; gir alle medlemmer hvis kontaktnummer inneholder minst ett siffer. For eksempel Robert Phil. | |
| ^ | Ocuco caret (^) forankrer kampen til begynnelsen av verdien. | SELECT * FRA `movies` WHERE `title` REGEXP '^[cd]'; viser alle filmer med tittel som starter med «c» eller «d». For eksempel, Code Navn Black, Daddy's Little Girls og Da Vinci Code. | |
| $ | Ocuco dollartegn ($) forankrer kampen til slutten av verdien. | VELG * FRA `filmer` HVOR `tittel` REGEXP 'kode$'; gir alle filmer med tittel som slutter på «kode». For eksempel Davinci Code. | |
| | | Ocuco vertikal strek (|) isolerer alternativer. | SELECT * FRA `movies` WHERE `title` REGEXP '^[cd]|^[u]'; viser alle filmer der tittelen starter med «c», «d» eller «u». For eksempel Code Navn Svart, Da Vinci Code, og Underverdenen – Awakening. | |
| \b | Ocuco ordgrense (\b) samsvarer med starten eller slutten av et ord. Den erstatter de eldre markørene [[:<:]] og [[:>:]], som MySQL 8.0 fjernet. | VELG * FRA `filmer` HVOR `tittel` REGEXP '\\bfor'; gir alle filmer med et ord som begynner med «for». For eksempel Forgetting Sarah Marshal. MySQL 5.7 er det tilsvarende mønsteret '[[:<:]]for'. | |
| [[:klasse:]] | Ocuco karakterklasse samsvarer med en navngitt gruppe med tegn: [[:alpha:]] for bokstaver, [[:space:]] for mellomrom, [[:punct:]] for tegnsetting og [[:upper:]] for store bokstaver. Merk deg dobbelt firkantede parenteser. | VELG * FRA `filmer` HVOR `tittel` REGEXP '^[[:alpha:][:mellomrom:]]+$'; viser alle filmer der tittelen kun inneholder bokstaver og mellomrom. For eksempel Forgetting Sarah Marshal, mens Pirates of the Caribean 4 er utelatt på grunn av sifferet. | |
Omvendt skråstrek (\) er escape-tegnet. Fordi MySQL analyserer strengen først og mønsteret deretter, må en litteral omvendt skråstrek skrives som en dobbel omvendt skråstrek (\\) inne i et REGEXP-mønster.
⚠️ Versjonsadvarsel: MySQL 8.0.4 erstattet den gamle motoren for regulære uttrykk med ICU-biblioteket. Ordmarkørene [[:<:]] og [[:>:]] ble fjernet i den utgivelsen, så mønstre kopiert fra eldre materiale mislykkes med en «syntaksfeil» på MySQL 8.0. Bruk \b i stedet.
Nå som alle metategn er definert, følger et rimelig spørsmål: når bør REGEXP erstatte den enklere LIKE-operatoren?
REGEXP vs LIKE: hvilken bør du bruke?
Begge operatorene filtrerer rader etter mønster, men de løser forskjellige problemer. LIKE forstår bare to symboler, mens REGEXP forstår hele metategnsettet vist ovenfor. Denne kraften har en kostnad, så valget er en avveining snarere enn en preferanse.
| Criterion | SOM | REGEXP |
|---|---|---|
| Mønstersymboler | Bare % og _ | Anchors, områder, alternering, kvantifikatorer, tegnklasser |
| Typisk bruk | Søk etter prefiks, suffiks og «inneholder» | Validering, flere alternativer, posisjonsbevisst matching |
| Indeksbruk | Mulig når mønsteret ikke starter med % | Bruker aldri en indeks |
| Returverdi | Sant eller usant | 1 eller 0, og NULL når en av operandene er NULL |
Velg LIKE for enkel matching, fordi den leser godt og fortsatt kan bruke en indeks. Velg REGEXP når et enkelt mønster må uttrykke flere regler samtidig, for eksempel «starter med c eller d og slutter med et siffer». I store tabeller, avgrens radene først med en indeksert betingelse, og bruk deretter REGEXP på det mindre settet.
MySQL 8.0 regulære uttrykkfunksjoner
REGEXP-operatoren svarer bare på ett spørsmål: samsvarer verdien med mønsteret? MySQL 8.0 har lagt til fire funksjoner som går lenger og lar deg finne, f.eks.tract, og skriv om den matchende teksten. Hver av dem aksepterer et valgfritt match_type-argument, der 'c' tvinger frem en sammenligning som skiller mellom store og små bokstaver og 'i' tvinger frem en sammenligning som ikke skiller mellom store og små bokstaver.
- REGEXP_LIKE(uttrykk, mønster) returnerer 1 når verdien samsvarer med mønsteret. Det er funksjonsformen til REGEXP-operatoren, og argumentet match_type gjør det eksplisitt å skille mellom store og små bokstaver.
- REGEXP_INSTR(uttrykk, mønster) returnerer posisjonen til det første tegnet i treffet, eller 0 når mønsteret ikke finnes.
- REGEXP_SUBSTR(uttrykk, mønster) returnerer selve den samsvarende delstrengen, som er nyttig for å hente et år, en kode eller et tall ut av en lengre tekstverdi.
- REGEXP_REPLACE(uttrykk, mønster, erstatning) returnerer verdien med hvert treff som erstattes, slik at den kan rense data i en SQL UPDATE-spørring.
SELECT title, REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title FROM `movies` WHERE REGEXP_LIKE(title, '[0-9]');
Spørringen ovenfor returnerer alle filmtitteler som inneholder et siffer, sammen med selve sifrene. MySQL 5.7 er disse funksjonene utilgjengelige, så REGEXP-operatoren er fortsatt det eneste alternativet.
