MySQL Reguljära uttryck (Regexp)
⚡ Smart sammanfattning
MySQL Reguljära uttryck (REGEXP) matchar kolumnvärden mot flexibla mönster som jokertecken inte kan uttrycka. Detta förklarar REGEXP-syntaxen, RLIKE-synonymen, alla metatecken som stöds, korrigerade frågeexempel mot myflixdb-databasen och de reguljära uttrycksfunktioner som lagts till i MySQL 8.0.

Vad är MySQL reguljära uttryck?
MySQL vanliga uttryck hjälpa dig att söka efter data som matchar komplexa kriterier. Ett reguljärt uttryck är ett mönster som beskriver formen på det värde du letar efter, snarare än själva värdet.
Om du redan har arbetat med MySQL jokertecken, kanske du undrar varför reguljära uttryck är värda att lära sig när LIKE ger liknande resultat. Svaret är uttryckskraft: jokertecken erbjuder bara två symboler, medan reguljära uttryck beskriver teckenintervall, alternativ, repetition och ordpositioner i ett enda mönster.
Med syftet fastställt presenteras i nästa avsnitt syntaxen du kommer att använda i varje REGEXP-fråga.
Grundläggande syntax för REGEXP
Den grundläggande syntaxen för ett reguljärt uttryck är följande.
SELECT * FROM table_name WHERE fieldname REGEXP 'pattern';
HÄR:
- "SELECT-sats" är standarden SELECT-sats.
- "WHERE fältnamn" är namnet på den kolumn som det reguljära uttrycket utförs på.
- "REGEXP 'mönster'" — REGEXP är operatorn för reguljära uttryck, och 'pattern' representerar mönstret som ska matchas. RLIKE är en synonym för REGEXP och returnerar samma resultat. För att undvika att förväxla det med LIKE-operatorn är det bättre att använda REGEXP.
Låt oss nu titta på ett praktiskt exempel.
SELECT * FROM `movies` WHERE `title` REGEXP 'code';
Ovanstående fråga söker efter alla filmtitlar som innehåller ordet ”kod”. Det spelar ingen roll om ”kod” visas i början, mitten eller slutet av titeln. Så länge titeln innehåller mönstret returneras raden.
Matcha början av ett värde med en teckenlista
Anta att vi vill ha filmer vars titlar börjar med a, b, c eller d, följt av ett valfritt antal andra tecken. Vi kombinerar en teckenlista med cirkumflektorns metateckne för att uppnå det resultatet.
SELECT * FROM `movies` WHERE `title` REGEXP '^[abcd]';
Exekvera skriptet ovan i MySQL Arbetsbänk mot myflixdb-databasen ger oss följande resultat.
| movie_id | rubricerade | direktör | year_released | kategori_id |
|---|---|---|---|---|
| 4 | Code Namn Svart | Edgar Jimz | 2010 | NULL |
| 5 | Pappas små flickor | NULL | 2007 | 8 |
| 6 | Änglar och demoner | NULL | 2007 | 6 |
| 7 | Davinci Code | NULL | 2007 | 6 |
I mönstret '^[abcd]' kräver cirkumflätet (^) att matchningen börjar i början av värdet, och teckenlistan [abcd] accepterar endast titlar vars första bokstav är a, b, c eller d. Jämförelsen är inte skiftlägeskänslig med standardsorteringen, vilket är anledningen till att “Code "Namn Svart" returneras.
Exkludera tecken med en negerad teckenlista
Låt oss nu modifiera skriptet och negera teckenlistan för att se vilka rader som returneras.
SELECT * FROM `movies` WHERE `title` REGEXP '^[^abcd]';
Exekvera skriptet ovan i MySQL Workbench mot myflixdb-databasen ger oss följande resultat.
| movie_id | rubricerade | direktör | year_released | kategori_id |
|---|---|---|---|---|
| 1 | Pirates of the Caribean 4 | Rob Marshall | 2011 | 1 |
| 2 | Att glömma Sarah Marshal | Nicholas Stoller | 2008 | 2 |
| 3 | X-Män | 2008 | ||
| 9 | Honey moonERS | John Schultz | 2005 | 8 |
| 16 | 67 % skyldig | 2012 | ||
| 17 | Diktatorn | Chalie Chaplie | 1920 | 7 |
| 18 | exempelfilm | Anonym | 8 | |
| 19 | film 3 | John Brown | 1920 | 8 |
Inuti en teckenlista ändrar cirkumflätets betydelse: '^[^abcd]' förankrar fortfarande matchningen i början, medan [^abcd] nu exkluderar alla titlar som börjar med ett av de omslutna tecknen.
Dessa två exempel använder endast ankare och teckenlistor. Nästa avsnitt täcker hela metateckenuppsättningen.
Reguljära uttrycksmetakaraktärer
Exemplen ovan visar den enklaste formen av ett reguljärt uttryck. Metatecken låter dig finjustera en mönstersökning: de uttrycker upprepning, alternativ, intervall och positioner. Tabellen nedan listar alla metatecken som stöds av MySQL REGEXP-operatorn, med ett korrigerat exempel för varje operator.
| Char | BESKRIVNING | Exempelvis | |
|---|---|---|---|
| * | Ocuco-landskapet asterisk (*) matchar noll (0) eller fler förekomster av enda tecken som föregår det. | VÄLJ * FRÅN filmer WHERE titel REGEXP 'da*'; matchar ett "d" följt av noll eller fler "a"-tecken, så Da Vinci Code och Daddy's Little Girls kvalificerar sig. Använd 'da+' när bokstaven "a" faktiskt måste finnas med. | |
| + | Ocuco-landskapet mer (+) matchar en eller flera förekomster av tecknet som föregår det. | SELECT * FRÅN `movies` WHERE `title` REGEXP 'mon+'; visar alla filmer som innehåller ”mon” följt av ett eller flera tecken ”n”. Till exempel, Änglar och demoner. | |
| ? | Ocuco-landskapet frågetecken (?) matchar noll (0) eller en förekomst av tecknet som föregår det. | SELECT * FROM `categories` WHERE `category_name` REGEXP 'com?'; matchar ”co” med ett valfritt ”m”. Till exempel komedi och romantisk komedi. | |
| . | Ocuco-landskapet prick (.) matchar vilket enskilt tecken som helst förutom en ny rad. | VÄLJ * FRÅN filmer WHERE `year_released` REGEXP '200.'; visar alla filmer som släpptes under ett år och börjar med "200" följt av en valfri karaktär. Till exempel 2005, 2007, 2008. | |
| [abc] | Ocuco-landskapet karaktärslista [abc] matchar något av de inneslutna tecknen. | SELECT * FRÅN `movies` WHERE `title` REGEXP '[vwxyz]'; visar alla filmer som innehåller en enskild karaktär från "vwxyz". Till exempel X-Men och Da Vinci Code. | |
| [^ abc] | Ocuco-landskapet negerad lista [^abc] matchar alla tecken förutom de som omges av tecken. | SELECT * FRÅN `movies` WHERE `title` REGEXP '^[^vwxyz]'; visar alla filmer vars titel inte börjar med en karaktär i ”vwxyz”. | |
| [AZ] | Ocuco-landskapet intervall [AZ] matchar valfri stor bokstav. | SELECT * FROM `members` WHERE `postal_address` REGEXP '[AZ]'; visar alla medlemmar vars postadress innehåller en bokstav mellan A och Ö. Till exempel Janet Jones med medlemsnummer 1. | |
| [Az] | Ocuco-landskapet intervall [az] matchar valfri gemen bokstav. | SELECT * FROM `members` WHERE `postal_address` REGEXP '[az]'; visar alla medlemmar vars postadress innehåller en bokstav mellan a och z. Observera att standardsorteringen är skiftlägesokänslig, så detta intervall matchar även versaler. | |
| [0-9] | Ocuco-landskapet intervall [0–9] matchar valfri siffra från 0 till 9. | VÄLJ * FRÅN `medlemmar` WHERE `kontaktnummer` REGEXP '[0-9]'; ger alla medlemmar vars kontaktnummer innehåller minst en siffra. Till exempel Robert Phil. | |
| ^ | Ocuco-landskapet caret (^) förankrar matchningen till början av värdet. | SELECT * FRÅN `movies` WHERE `title` REGEXP '^[cd]'; visar alla filmer vars titel börjar med "c" eller "d". Till exempel, Code Namn Black, Daddy's Little Girls och Da Vinci Code. | |
| $ | Ocuco-landskapet dollartecken ($) förankrar matchningen till slutet av värdet. | VÄLJ * FRÅN `filmer` WHERE `titel` REGEXP 'kod$'; ger alla filmer vars titel slutar på ”kod”. Till exempel Davinci Code. | |
| | | Ocuco-landskapet vertikal streck (|) isolerar alternativ. | SELECT * FRÅN `movies` WHERE `title` REGEXP '^[cd]|^[u]'; visar alla filmer vars titel börjar med "c", "d" eller "u". Till exempel Code Namn Black, Da Vinci Code, och Underjorden – AwakenIng. | |
| \b | Ocuco-landskapet ordgräns (\b) matchar början eller slutet av ett ord. Den ersätter de äldre markörerna [[:<:]] och [[:>:]], vilka MySQL 8.0 borttagen. | VÄLJ * FRÅN `filmer` WHERE `titel` REGEXP '\\bför'; ger alla filmer med ett ord som börjar med ”för”. Till exempel Forgetting Sarah Marshal. MySQL 5.7 är motsvarande mönster '[[:<:]]för'. | |
| [[:klass:]] | Ocuco-landskapet karaktär klass matchar en namngiven grupp av tecken: [[:alpha:]] för bokstäver, [[:space:]] för mellanslag, [[:punct:]] för interpunktion och [[:upper:]] för versaler. Observera dubbla hakparenteser. | VÄLJ * FRÅN `filmer` WHERE `titel` REGEXP '^[[:alpha:][:mellanslag:]]+$'; visar alla filmer vars titel endast innehåller bokstäver och mellanslag. Till exempel Forgetting Sarah Marshal, medan Pirates of the Caribean 4 utelämnas på grund av siffran. | |
Bakåtsnedstrecket (\) är escape-tecknet. Eftersom MySQL tolkar strängen först och mönstret sedan, måste ett litteralt omvänt snedstreck skrivas som ett dubbelt omvänt snedstreck (\\) inuti ett REGEXP-mönster.
⚠️ Versionsvarning: MySQL 8.0.4 ersatte den gamla reguljära uttrycksmotorn med ICU-biblioteket. Ordmarkörerna [[:<:]] och [[:>:]] togs bort i den utgåvan, så mönster som kopierats från äldre material misslyckas med ett "syntaxfel" på MySQL 8.0. Använd \b istället.
Nu när varje metatecken är definierat uppstår en rimlig fråga: när ska REGEXP ersätta den enklare LIKE-operatorn?
REGEXP vs LIKE: vilken ska du använda?
Båda operatorerna filtrerar rader efter mönster, men de löser olika problem. LIKE förstår endast två symboler, medan REGEXP förstår hela metateckenuppsättningen som visas ovan. Den kraften har ett pris, så valet är en avvägning snarare än en preferens.
| Kriterium | SOM | REGEXP |
|---|---|---|
| Mönstersymboler | Endast % och _ | Anchors, intervall, alternering, kvantifierare, teckenklasser |
| Typisk användning | Prefix-, suffix- och "innehåller"-sökningar | Validering, flera alternativ, positionsmedveten matchning |
| Indexanvändning | Möjligt när mönstret inte börjar med % | Använder aldrig ett index |
| Returvärde | Sant eller falskt | 1 eller 0, och NULL när endera operanden är NULL |
Välj LIKE för enkel matchning, eftersom den läser bra och fortfarande kan använda ett index. Välj REGEXP när ett enda mönster måste uttrycka flera regler samtidigt, till exempel "börjar med c eller d och slutar med en siffra". I stora tabeller, begränsa raderna först med ett indexerat villkor och använd sedan REGEXP på den mindre mängden.
MySQL 8.0 reguljära uttrycksfunktioner
REGEXP-operatorn besvarar bara en fråga: matchar värdet mönstret? MySQL 8.0 lade till fyra funktioner som går längre och låter dig lokalisera, t.ex.tract, och skriv om den matchande texten. Var och en accepterar ett valfritt match_type-argument, där 'c' tvingar fram en skiftlägeskänslig jämförelse och 'i' tvingar fram en skiftlägesobegränsande jämförelse.
- REGEXP_LIKE(uttryck, mönster) returnerar 1 när värdet matchar mönstret. Det är funktionsformen för REGEXP-operatorn, och argumentet match_type gör skiftlägeskänsligheten explicit.
- REGEXP_INSTR(uttryck, mönster) returnerar positionen för det första tecknet i matchningen, eller 0 när mönstret inte hittas.
- REGEXP_SUBSTR(uttryck, mönster) returnerar själva matchande delsträngen, vilket är användbart för att hämta ett år, en kod eller ett tal ur ett längre textvärde.
- REGEXP_ERSÄTT(uttryck, mönster, ersättning) returnerar värdet med varje matchning som ersätts, så att den kan rensa data inuti en SQL UPDATE-fråga.
SELECT title, REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title FROM `movies` WHERE REGEXP_LIKE(title, '[0-9]');
Frågan ovan returnerar varje filmtitel som innehåller en siffra, tillsammans med själva siffrorna. MySQL 5.7 är dessa funktioner inte tillgängliga, så REGEXP-operatorn är fortfarande det enda alternativet.
