MySQL Reguliere expressies (Regexp)

โšก Slimme samenvatting

MySQL Reguliere expressies (REGEXP) vergelijken kolomwaarden met flexibele patronen die niet met jokertekens kunnen worden uitgedrukt. Deze uitleg beschrijft de REGEXP-syntaxis, het synoniem RLIKE, alle ondersteunde metatekens, gecorrigeerde queryvoorbeelden voor de myflixdb-database en de reguliere expressiefuncties die zijn toegevoegd. MySQL 8.0.

  • ๐Ÿ” Kern Operavoor: REGEXP vergelijkt een kolom met een patroon en retourneert 1 bij een overeenkomst, terwijl RLIKE een exact synoniem is van REGEXP.
  • ๐Ÿงฉ Patronen Anchors: Het dakje (^) verankert de overeenkomst aan het begin van de waarde, en het dollarteken ($) verankert deze aan het einde.
  • ๐Ÿ”ค Personagelijsten: [abcd] komt overeen met elk ingesloten teken, en [^abcd] sluit elk ingesloten teken uit van de resultaten.
  • โž• Kwantificatoren: Het asterisk-, plus- en vraagtekensymbool hebben betrekking op het enkele teken dat eraan voorafgaat, niet op de hele tekenreeks.
  • ๐Ÿ›ก๏ธ Escaping Regel: Een letterlijke backslash moet binnen een patroon verdubbeld worden, omdat MySQL verwerkt de tekenreeks twee keer.
  • ๐Ÿ†• Versiewijziging: MySQL In versie 8.0 is overgestapt naar de ICU-engine, zijn [[:<:]] en [[:>:]] vervangen door \b, en zijn REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR en REGEXP_INSTR toegevoegd.
  • โšก Prestatieopmerking: REGEXP gebruikt nooit een index, dus filter eerst de rijen met een geรฏndexeerde voorwaarde wanneer de query dat toelaat.

Wat zijn MySQL reguliere expressies?

MySQL normale uitdrukkingen Hiermee kunt u zoeken naar gegevens die aan complexe criteria voldoen. Een reguliere expressie is een patroon dat de vorm beschrijft van de waarde waarnaar u zoekt, in plaats van de waarde zelf.

Als u al eerder met MySQL wildcardsJe vraagt โ€‹โ€‹je misschien af โ€‹โ€‹waarom het de moeite waard is om reguliere expressies te leren als LIKE vergelijkbare resultaten oplevert. Het antwoord is expressieve kracht: jokers bieden slechts twee symbolen, terwijl reguliere expressies tekenbereiken, alternatieven, herhalingen en woordposities in รฉรฉn patroon beschrijven.

Nu het doel is vastgesteld, introduceert het volgende gedeelte de syntaxis die u in elke REGEXP-query zult gebruiken.

Basissyntaxis van REGEXP

De basissyntaxis voor een reguliere expressie is als volgt.

SELECT * FROM table_name
WHERE fieldname REGEXP 'pattern';

HIER:

  • โ€œSELECT-instructieโ€ is de standaard SELECT-instructie.
  • โ€œWHERE veldnaamโ€ is de naam van de kolom waarop de reguliere expressie wordt uitgevoerd.
  • โ€œREGEXP 'patroon'โ€ โ€” REGEXP is de operator voor reguliere expressies, en 'pattern' staat voor het patroon dat moet worden vergeleken. RLIKE is een synoniem voor REGEXP en levert dezelfde resultaten op. Om verwarring met de LIKE-operator te voorkomen, is het beter om REGEXP te gebruiken.

Laten we nu eens naar een praktisch voorbeeld kijken.

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

De bovenstaande zoekopdracht zoekt naar alle filmtitels die het woord 'code' bevatten. Het maakt niet uit of 'code' aan het begin, in het midden of aan het einde van de titel staat. Zolang de titel het patroon bevat, wordt de betreffende rij geretourneerd.

Het begin van een waarde vergelijken met een tekenlijst.

Stel dat we films willen waarvan de titels beginnen met een a, b, c of d, gevolgd door een willekeurig aantal andere tekens. We combineren een lijst met tekens met het metateken caret om dat resultaat te bereiken.

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

Voer het bovenstaande script uit in MySQL Werkbank Een vergelijking met de myflixdb-database levert de volgende resultaten op.

film_id titel directeur jaar_uitgebracht categorie ID
4 Code Naam Zwart Edgar Jimz 2010 NULL
5 Papa's kleine meisjes NULL 2007 8
6 Engelen en duivels NULL 2007 6
7 Davinci Code NULL 2007 6

In het patroon '^[abcd]' vereist het caret-teken (^) dat de overeenkomst aan het begin van de waarde begint, en de tekenlijst [abcd] accepteert alleen titels waarvan de eerste letter a, b, c of d is. De vergelijking is niet hoofdlettergevoelig bij de standaard sortering, vandaar "Code De naam "Black" wordt geretourneerd.

Personages met een ontkende personagelijst worden uitgesloten.

Laten we nu het script aanpassen en de tekenlijst omkeren om te zien welke rijen worden geretourneerd.

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

Voer het bovenstaande script uit in MySQL Workbench levert de volgende resultaten op bij het gebruik van de myflixdb-database.

film_id titel directeur jaar_uitgebracht categorie ID
1 Piraten van het Caribisch gebied 4 Rob Marshall 2011 1
2 Sarah Marshal vergeten Nicholas Stoller 2008 2
3 X-Men 2008
9 Honey mooners John Schulz 2005 8
16 67% Schuldig 2012
17 The Great Dictator Chalie Chaplie 1920 7
18 voorbeeldfilm Anoniem 8
19 film 3 John Brown 1920 8

Binnen een lijst met tekens verandert de betekenis van het caret-teken: '^[^abcd]' verankert de overeenkomst nog steeds aan het begin, terwijl [^abcd] nu elke titel uitsluit die begint met een van de tekens tussen haakjes.

Deze twee voorbeelden gebruiken alleen ankers en tekenlijsten. In het volgende gedeelte wordt de volledige set met metatekens behandeld.

Metatekens voor reguliere expressies

De bovenstaande voorbeelden tonen de eenvoudigste vorm van een reguliere expressie. Metatekens kunt u een patroonzoekopdracht verfijnen: ze drukken herhaling, alternatieven, bereiken en posities uit. De onderstaande tabel geeft een overzicht van alle metatekens die door de reguliere expressie worden ondersteund. MySQL REGEXP-operator, met voor elk een gecorrigeerd voorbeeld.

Verkolen Beschrijving Voorbeeld
* De sterretje (*) komt overeen met nul (0) of meer instanties van de enkel karakter dat eraan voorafgaat. SELECTEER * UIT films WAAR titel REGEXP 'da*'; komt overeen met een "d" gevolgd door nul of meer "a"-tekens, dus Da Vinci Code En Daddy's Little Girls komen ook in aanmerking. Gebruik 'da+' wanneer de letter 'a' daadwerkelijk aanwezig moet zijn.
+ De meer (+) komt overeen met een of meer instanties van het teken dat eraan voorafgaat. SELECTEER * UIT `films` WAAR `titel` REGEXP 'mon+'; Geeft alle films weer die "mon" bevatten, gevolgd door een of meer "n"-tekens. Bijvoorbeeld: Angels and Demons.
? De vraagteken (?) komt overeen met nul (0) of รฉรฉn instantie van het teken dat eraan voorafgaat. SELECT * VAN `categorieรซn` WAAR `categorie_naam` REGEXP 'com?'; combineert โ€œcoโ€ met een optionele โ€œmโ€. Bijvoorbeeld: comedy en romantic comedy.
. De punt (.) Komt overeen met elk willekeurig teken, behalve een nieuwe regel. SELECT * UIT films WAAR `year_released` REGEXP '200.'; Geeft alle films weer die zijn uitgebracht in een jaar dat begint met "200", gevolgd door een willekeurig teken. Bijvoorbeeld: 2005, 2007, 2008.
[abc] De tekenlijst [abc] komt overeen met een van de ingesloten tekens. SELECTEER * UIT `films` WAAR `titel` REGEXP '[vwxyz]'; Geeft alle films weer waarin ook maar รฉรฉn personage uit "vwxyz" voorkomt. Bijvoorbeeld: X-Men en Da Vinci. Code.
[^ abc] De ontkende lijst [^abc] Komt overeen met elk teken, behalve de tekens die tussen haakjes staan. SELECT * VAN `films` WAAR `titel` REGEXP '^[^vwxyz]'; Geeft alle films weer waarvan de titel niet begint met een letter uit "vwxyz".
[AZ] De bereik [AZ] komt overeen met elke hoofdletter. SELECT * VAN `leden` โ€‹โ€‹WAAR `postadres` REGEXP '[AZ]'; Geeft alle leden weer van wie het postadres een letter tussen A en Z bevat. Bijvoorbeeld Janet Jones met lidmaatschapsnummer 1.
[az] De bereik [az] komt overeen met elke kleine letter. SELECT * VAN `leden` โ€‹โ€‹WAAR `postadres` REGEXP '[az]'; Geeft alle leden weer waarvan het postadres een letter tussen a en z bevat. Merk op dat de standaard sortering niet hoofdlettergevoelig is, dus dit bereik komt ook overeen met hoofdletters.
[0-9] De bereik [0-9] Komt overeen met elk cijfer van 0 tot en met 9. SELECT * FROM `members` WHERE `contact_number` REGEXP '[0-9]'; Geeft alle leden weer waarvan het contactnummer minstens รฉรฉn cijfer bevat. Bijvoorbeeld: Robert Phil.
^ De dakje (^) verankert de overeenkomst aan het begin van de waarde. SELECT * VAN `films` WAAR `titel` REGEXP '^[cd]'; Geeft alle films weer waarvan de titel begint met een "c" of een "d". Bijvoorbeeld: Code Name Black, Daddy's Little Girls en Da Vinci Code.
$ De dollarteken ($) verankert de overeenkomst aan het einde van de waarde. SELECT * FROM `movies` WHERE `title` REGEXP 'code$'; Geeft alle films weer waarvan de titel eindigt op "code". Bijvoorbeeld: Davinci Code.
| De verticale balk (|) isoleert alternatieven. SELECT * VAN `films` WAAR `titel` REGEXP '^[cd]|^[u]'; Geeft alle films weer waarvan de titel begint met een "c", een "d" of een "u". Bijvoorbeeld: Code Naam: Black, Da Vinci Codeen Onderwereld โ€“ AwakenIng.
\b De woordgrens (\b) komt overeen met het begin of het einde van een woord. Het vervangt de oudere markeringen [[:<:]] en [[:>:]], die MySQL Versie 8.0 is verwijderd. SELECT * FROM `movies` WHERE `title` REGEXP '\\bfor'; Geeft alle films weer waarvan het woord begint met "for". Bijvoorbeeld: Forgetting Sarah Marshal. MySQL 5.7 Het equivalente patroon is '[[:<:]]for'.
[[:klas:]] De tekenklasse komt overeen met een benoemde groep tekens: [[:alpha:]] voor letters, [[:space:]] voor spaties, [[:punct:]] voor leestekens en [[:upper:]] voor hoofdletters. Let op de verdubbelen vierkante haakjes. SELECT * FROM `movies` WHERE `title` REGEXP '^[[:alpha:][:space:]]+$'; Geeft alle films weer waarvan de titel alleen letters en spaties bevat. Bijvoorbeeld: Forgetting Sarah Marshal, terwijl Pirates of the Caribbean 4 wordt weggelaten vanwege het cijfer.

De backslash (\) is het escape-teken. Omdat MySQL De string wordt eerst geparseerd en daarna het patroon; een letterlijke backslash moet binnen een REGEXP-patroon als een dubbele backslash (\\) worden geschreven.

โš ๏ธ Versie-waarschuwing: MySQL In versie 8.0.4 werd de oude engine voor reguliere expressies vervangen door de ICU-bibliotheek. De woordmarkeringen [[:<:]] en [[:>:]] werden in die release verwijderd, waardoor patronen die van ouder materiaal zijn gekopieerd, een "syntaxfout" geven. MySQL 8.0. Gebruik in plaats daarvan \b.

Nu alle metatekens gedefinieerd zijn, rijst de terechte vraag: wanneer moet REGEXP de eenvoudigere LIKE-operator vervangen?

REGEXP versus LIKE: welke moet je gebruiken?

Beide operators filteren rijen op basis van een patroon, maar ze lossen verschillende problemen op. LIKE begrijpt slechts twee symbolen, terwijl REGEXP de volledige set metatekens begrijpt die hierboven is weergegeven. Die kracht heeft een prijs, dus de keuze is een afweging in plaats van een voorkeur.

Criterium LIKE REGEXP
Patroonsymbolen % en _ alleen Anchors, bereiken, afwisseling, kwantoren, tekenklassen
Typisch gebruik Zoekopdrachten met voorvoegsels, achtervoegsels en "bevat" Validatie, meerdere alternatieven, positiebewuste matching
Indexgebruik Mogelijk wanneer het patroon niet met een % begint. Gebruikt nooit een index
Winstwaarde Waar of niet waar 1 of 0, en NULL wanneer een van beide operanden NULL is.

Kies LIKE voor eenvoudige overeenkomsten, omdat het goed leesbaar is en nog steeds een index kan gebruiken. Kies REGEXP wanneer een enkel patroon meerdere regels tegelijk moet uitdrukken, zoals "begint met c of d en eindigt met een cijfer". Bij grote tabellen kunt u de rijen eerst verkleinen met een geรฏndexeerde voorwaarde en vervolgens REGEXP toepassen op die kleinere set.

MySQL 8.0 reguliere expressiefuncties

De REGEXP-operator beantwoordt slechts รฉรฉn vraag: komt de waarde overeen met het patroon? MySQL Versie 8.0 voegde vier functies toe die verder gaan en waarmee je bijvoorbeeld kunt lokaliseren.tract, en herschrijf de overeenkomende tekst. Elk accepteert een optioneel argument match_type, waarbij 'c' een hoofdlettergevoelige vergelijking afdwingt en 'i' een hoofdletterongevoelige vergelijking.

  • REGEXP_LIKE(expr, pattern) Retourneert 1 wanneer de waarde overeenkomt met het patroon. Het is de functievorm van de REGEXP-operator, en het argument match_type maakt hoofdlettergevoeligheid expliciet.
  • REGEXP_INSTR(expr, patroon) Geeft de positie van het eerste teken van de overeenkomst terug, of 0 als het patroon niet wordt gevonden.
  • REGEXP_SUBSTR(expr, patroon) Retourneert de overeenkomende substring zelf, wat handig is om bijvoorbeeld een jaartal, een code of een getal uit een langere tekstwaarde te halen.
  • REGEXP_REPLACE(expr, patroon, vervanging) retourneert de waarde waarbij elke overeenkomst is vervangen, zodat gegevens binnen een kunnen worden opgeschoond. SQL UPDATE-query.
SELECT title,
       REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title
FROM `movies`
WHERE REGEXP_LIKE(title, '[0-9]');

De bovenstaande query retourneert alle filmtitels die een cijfer bevatten, samen met de cijfers zelf. MySQL 5.7 Deze functies zijn niet beschikbaar, dus de REGEXP-operator blijft de enige optie.

Veelgestelde vragen

Niet standaard. REGEXP volgt de sortering van de kolom, en de standaardsorteringen zijn niet hoofdlettergevoelig. Voeg het trefwoord BINARY toe vรณรณr de kolom, of roep REGEXP_LIKE aan met het overeenkomsttype 'c', om een โ€‹โ€‹hoofdlettergevoelige vergelijking af te dwingen.

Er is geen functioneel verschil. RLIKE is een synoniem van REGEXP. MySQL Houdt rekening met compatibiliteit. REGEXP heeft in de praktijk de voorkeur, omdat RLIKE gemakkelijk verward kan worden met iets anders. ALS operator gebruikt voor jokers.

REGEXP kan geen index gebruiken, dus MySQL Het patroon wordt rij voor rij geรซvalueerd. De gescande rijen worden eerst gereduceerd met behulp van een index, een datumbereik of een volledige tekstindex, waarna de reguliere expressie op de kleinere resultatenset wordt toegepast.

Ja. AI-assistenten zetten een regel in gewone taal om in een reguliere expressie (REGEXP) en leggen elk metateken uit. Test het resultaat in MySQL Werkbank tegen voorbeeldrijen, omdat een enkele verkeerd geplaatste ankerpunt de hele resultaatset verandert.

Ja. AI-assistenten genereren REGEXP_REPLACE-instructies die leestekens verwijderen, telefoonnummers normaliseren of overtollige spaties verwijderen. Voer het patroon eerst uit in een SELECT-statement, controleer de herschreven waarden en pas het pas daarna toe in een UPDATE-verklaring.

Vat dit bericht samen met: