MySQL Regulære udtryk (Regexp)
⚡ Smart opsummering
MySQL Regulære udtryk (REGEXP) matcher kolonneværdier mod fleksible mønstre, som jokertegn ikke kan udtrykke. Dette forklarer REGEXP-syntaksen, RLIKE-synonymet, alle understøttede metategn, korrigerede forespørgselseksempler mod myflixdb-databasen og de regulære udtryksfunktioner, der er tilføjet i MySQL 8.0.

Hvad er MySQL regulære udtryk?
MySQL regulære udtryk hjælpe dig med at søge efter data, der matcher komplekse kriterier. Et regulært udtryk er et mønster, der beskriver formen på den værdi, du leder efter, snarere end selve værdien.
Hvis du allerede har arbejdet med MySQL jokertegn, spørger du måske, hvorfor det er værd at lære regulære udtryk, når LIKE giver lignende resultater. Svaret er udtrykskraft: jokertegn tilbyder kun to symboler, mens regulære udtryk beskriver tegnintervaller, alternativer, gentagelser og ordpositioner i et enkelt mønster.
Med formålet fastlagt introducerer næste afsnit den syntaks, du vil bruge i hver REGEXP-forespørgsel.
Grundlæggende syntaks for REGEXP
Den grundlæggende syntaks for et regulært udtryk er som følger.
SELECT * FROM table_name WHERE fieldname REGEXP 'pattern';
HER:
- "SELECT-sætning" er standarden SELECT erklæring.
- "WHERE feltnavn" er navnet på den kolonne, hvor det regulære udtryk udføres.
- "REGEXP 'mønster'" — REGEXP er operatoren for regulære udtryk, og 'pattern' repræsenterer det mønster, der skal matches. RLIKE er en synonym for REGEXP og returnerer de samme resultater. For at undgå at forveksle den med LIKE-operatoren er det bedre at bruge REGEXP.
Lad os nu se på et praktisk eksempel.
SELECT * FROM `movies` WHERE `title` REGEXP 'code';
Ovenstående forespørgsel søger efter alle filmtitler, der indeholder ordet "kode". Det er ligegyldigt, om "kode" vises i begyndelsen, midten eller i slutningen af titlen. Så længe titlen indeholder mønsteret, returneres rækken.
Match starten af en værdi med en tegnliste
Antag, at vi ønsker de film, hvis titler starter med a, b, c eller d, efterfulgt af et hvilket som helst antal andre tegn. Vi kombinerer en tegnliste med cirkumfleksmetategn for at opnå dette resultat.
SELECT * FROM `movies` WHERE `title` REGEXP '^[abcd]';
Udførelse af ovenstående script i MySQL Workbench mod myflixdb-databasen giver os følgende resultater.
| film_id | titel | direktør | år_udgivet | kategori_id |
|---|---|---|---|---|
| 4 | Code Navn Sort | Edgar Jimz | 2010 | NULL |
| 5 | Daddy's Little Girls | NULL | 2007 | 8 |
| 6 | Engle og dæmoner | NULL | 2007 | 6 |
| 7 | Davinci Code | NULL | 2007 | 6 |
I mønsteret '^[abcd]' kræver cirkumflekstegnet (^), at matchen starter i begyndelsen af værdien, og tegnlisten [abcd] accepterer kun titler, hvis første bogstav er a, b, c eller d. Sammenligningen skelner ikke mellem store og små bogstaver under standardsorteringen, hvilket er grunden til, at “Code "Navn Sort" returneres.
Udelukkelse af tegn med en negeret tegnliste
Lad os nu ændre scriptet og negere tegnlisten for at se, hvilke rækker der returneres.
SELECT * FROM `movies` WHERE `title` REGEXP '^[^abcd]';
Udførelse af ovenstående script i MySQL Workbench mod myflixdb-databasen giver os følgende resultater.
| film_id | titel | direktør | år_udgivet | kategori_id |
|---|---|---|---|---|
| 1 | Pirates of the Caribean 4 | Rob Marshall | 2011 | 1 |
| 2 | Glemte Sarah Marshal | Nicholas Stoller | 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 |
Inde i en tegnliste ændrer cirkumflekstegnet betydning: '^[^abcd]' forankrer stadig matchen i begyndelsen, mens [^abcd] nu ekskluderer alle titler, der starter med et af de omsluttede tegn.
Disse to eksempler bruger kun ankre og tegnlister. Det næste afsnit dækker det fulde metategnsæt.
Regulære udtryks metakarakterer
Eksemplerne ovenfor viser den enkleste form for et regulært udtryk. Metategn giver dig mulighed for at finjustere en mønstersøgning: de udtrykker gentagelse, alternativer, intervaller og positioner. Tabellen nedenfor viser alle metategn, der understøttes af MySQL REGEXP-operatoren, med et rettet eksempel for hver enkelt.
| Char | Beskrivelse | Eksempel | |
|---|---|---|---|
| * | stjerne (*) matcher nul (0) eller flere forekomster af enkelt tegn der går forud for det. | VÆLG * FRA film WHERE titel REGEXP 'da*'; matcher et "d" efterfulgt af nul eller flere "a"-tegn, så Da Vinci Code og Daddy's Little Girls kvalificerer sig. Brug 'da+', når bogstavet "a" faktisk skal være til stede. | |
| + | mere (+) matcher en eller flere forekomster af det tegn, der går forud for den. | VÆLG * FRA `movies` WHERE `title` REGEXP 'mon+'; viser alle film, der indeholder "mon" efterfulgt af et eller flere "n"-tegn. For eksempel, Engle og Dæmoner. | |
| ? | spørgsmålstegn (?) matcher nul (0) eller én forekomst af det tegn, der går forud for det. | VÆLG * FRA `kategorier` WHERE `kategorinavn` REGEXP 'com?'; matcher "co" med et valgfrit "m". For eksempel komedie og romantisk komedie. | |
| . | prik (.) matcher et hvilket som helst enkelt tegn undtagen en ny linje. | VÆLG * FRA film, HVOR `year_released` REGEXP '200.'; viser alle film udgivet i et år startende med "200" efterfulgt af en vilkårlig karakter. For eksempel 2005, 2007, 2008. | |
| [abc] | karakterliste [abc] matcher et af de omsluttede tegn. | SELECT * FRA `movies` WHERE `title` REGEXP '[vwxyz]'; viser alle film, der indeholder en enkelt karakter fra “vwxyz”. For eksempel X-Men og Da Vinci Code. | |
| [^ abc] | negeret liste [^abc] matcher alle tegn undtagen dem, der er omsluttet. | VÆLG * FRA `movies` WHERE `title` REGEXP '^[^vwxyz]'; viser alle film, hvis titel ikke starter med en karakter i “vwxyz”. | |
| [AZ] | rækkevidde [AZ] matcher et hvilket som helst stort bogstav. | SELECT * FRA `members` WHERE `postal_address` REGEXP '[AZ]'; angiver alle medlemmer, hvis postadresse indeholder et bogstav mellem A og Z. For eksempel Janet Jones med medlemsnummer 1. | |
| [az] | rækkevidde [az] matcher et hvilket som helst lille bogstav. | SELECT * FRA `members` WHERE `postal_address` REGEXP '[az]'; viser alle medlemmer, hvis postadresse indeholder et bogstav mellem a og z. Bemærk, at standardsorteringen ikke skelner mellem store og små bogstaver, så dette interval matcher også store bogstaver. | |
| [0-9] | område [0-9] matcher et hvilket som helst ciffer fra 0 til 9. | VÆLG * FRA `medlemmer` HVOR `kontaktnummer` REGEXP '[0-9]'; viser alle medlemmer, hvis kontaktnummer indeholder mindst ét ciffer. For eksempel Robert Phil. | |
| ^ | karet (^) forankrer kampen til begyndelsen af værdien. | SELECT * FRA `movies` WHERE `title` REGEXP '^[cd]'; viser alle film, hvis titel starter med "c" eller "d". For eksempel Code Navn Black, Daddy's Little Girls og Da Vinci Code. | |
| $ | dollartegn ($) forankrer kampen til slutningen af værdien. | VÆLG * FRA `film` HVOR `titel` REGEXP 'kode$'; viser alle film, hvis titel ender på "kode". For eksempel Davinci Code. | |
| | | lodret streg (|) isolerer alternativer. | SELECT * FRA `movies` WHERE `title` REGEXP '^[cd]|^[u]'; viser alle film, hvis titel starter med "c", "d" eller "u". For eksempel Code Navn Black, Da Vinci Codeog Underverdenen – AwakenIng. | |
| \b | ordgrænse (\b) matcher starten eller slutningen af et ord. Den erstatter de ældre [[:<:]] og [[:>:]] markører, som MySQL 8.0 fjernet. | VÆLG * FRA `film` HVOR `titel` REGEXP '\\bfor'; viser alle film med et ord, der starter med "for". For eksempel Forgetting Sarah Marshal. MySQL 5.7 er det tilsvarende mønster '[[:<:]]for'. | |
| [[:klasse:]] | karakterklasse matcher en navngiven gruppe af tegn: [[:alpha:]] for bogstaver, [[:space:]] for mellemrum, [[:punct:]] for tegnsætning og [[:upper:]] for store bogstaver. Bemærk fordoble firkantede parenteser. | VÆLG * FRA `film` HVOR `titel` REGEXP '^[[:alpha:][:mellemrum:]]+$'; viser alle film, hvis titel kun indeholder bogstaver og mellemrum. For eksempel Forgetting Sarah Marshal, mens Pirates of the Caribean 4 er udeladt på grund af cifferet. | |
Omvendt skråstreg (\) er escape-tegnet. Fordi MySQL analyserer strengen først og mønsteret derefter, skal et literalt omvendt skråstreg skrives som et dobbelt omvendt skråstreg (\\) inde i et REGEXP-mønster.
⚠️ Versionsadvarsel: MySQL 8.0.4 erstattede den gamle regulære udtryksmotor med ICU-biblioteket. Ordmarkørerne [[:<:]] og [[:>:]] blev fjernet i den udgivelse, så mønstre kopieret fra ældre materiale fejler med en "syntaksfejl" på MySQL 8.0. Brug \b i stedet.
Nu hvor alle metategn er defineret, opstår et rimeligt spørgsmål: hvornår skal REGEXP erstatte den enklere LIKE-operator?
REGEXP vs LIKE: hvilken skal du bruge?
Begge operatorer filtrerer rækker efter mønster, men de løser forskellige problemer. LIKE forstår kun to symboler, mens REGEXP forstår det fulde metategnsæt vist ovenfor. Den styrke har en pris, så valget er et kompromis snarere end en præference.
| Kriterium | LIKE | REGEXP |
|---|---|---|
| Mønstersymboler | Kun % og _ | Anchors, intervaller, alternering, kvantifikatorer, tegnklasser |
| Typisk brug | Søgninger efter præfiks, suffiks og "indeholder" | Validering, flere alternativer, positionsbevidst matchning |
| Indeksbrug | Muligt når mønsteret ikke starter med % | Bruger aldrig et indeks |
| Returværdi | Sandt eller falsk | 1 eller 0, og NULL når en af operanderne er NULL |
Vælg LIKE for ligefrem matchning, fordi det læses nemt og stadig kan bruge et indeks. Vælg REGEXP, når et enkelt mønster skal udtrykke flere regler på én gang, f.eks. "starter med c eller d og slutter med et ciffer". I store tabeller skal du først indsnævre rækkerne med en indekseret betingelse, og derefter anvende REGEXP på det mindre sæt.
MySQL 8.0 regulære udtryksfunktioner
REGEXP-operatoren besvarer kun ét spørgsmål: stemmer værdien overens med mønsteret? MySQL 8.0 har tilføjet fire funktioner, der går endnu videre og lader dig finde, f.eks.tract, og omskriv den matchende tekst. Hver af dem accepterer et valgfrit match_type-argument, hvor 'c' gennemtvinger en sammenligning, der skelner mellem store og små bogstaver, og 'i' gennemtvinger en sammenligning, der ikke skelner mellem store og små bogstaver.
- REGEXP_LIKE(udtryk, mønster) returnerer 1, når værdien matcher mønsteret. Det er funktionsformen for REGEXP-operatoren, og argumentet match_type gør forskellen på store og små bogstaver eksplicit.
- REGEXP_INSTR(udtryk, mønster) returnerer positionen for det første tegn i matchen, eller 0 når mønsteret ikke findes.
- REGEXP_SUBSTR(udtryk, mønster) returnerer selve den matchende delstreng, hvilket er nyttigt til at trække et år, en kode eller et tal ud af en længere tekstværdi.
- REGEXP_REPLACE(udtryk, mønster, erstatning) returnerer værdien med hvert match, der erstattes, så den kan rense data i en SQL UPDATE-forespørgsel.
SELECT title, REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title FROM `movies` WHERE REGEXP_LIKE(title, '[0-9]');
Ovenstående forespørgsel returnerer alle filmtitler, der indeholder et ciffer, sammen med selve cifrene. MySQL 5.7 er disse funktioner ikke tilgængelige, så REGEXP-operatoren er fortsat den eneste mulighed.
