MySQL Säännölliset lausekkeet (Regexp)
⚡ Älykäs yhteenveto
MySQL Säännölliset lausekkeet (REGEXP) yhdistävät sarakearvoja joustaviin malleihin, joita jokerimerkit eivät voi ilmaista. Tämä selittää REGEXP-syntaksin, RLIKE-synonyymin, kaikki tuetut metamerkit, korjatut kyselyesimerkit myflixdb-tietokantaa vasten ja lisätyt säännöllisten lausekkeiden funktiot. MySQL 8.0.
Mitä ovat MySQL säännölliset lausekkeet?
MySQL säännölliset lausekkeet auttavat sinua etsimään monimutkaisia kriteerejä vastaavaa dataa. Säännöllinen lauseke on malli, joka kuvaa etsimäsi arvon muotoa eikä itse arvoa.
Jos olet jo työskennellyt MySQL jokerimerkitSaatat kysyä, miksi säännöllisten lausekkeiden oppiminen kannattaa, kun LIKE tuottaa samanlaisia tuloksia. Vastaus on ilmaisuvoima: jokerimerkit tarjoavat vain kaksi symbolia, kun taas säännölliset lausekkeet kuvaavat merkkialueita, vaihtoehtoja, toistoja ja sanojen sijainteja yhdessä mallissa.
Kun tarkoitus on selvitetty, seuraavassa osiossa esitellään syntaksi, jota käytät jokaisessa säännöllisessä lausekkeessa (REGEXP).
REGEXP:n perussyntaksi
Säännöllisen lausekkeen perussyntaksi on seuraava.
SELECT * FROM table_name WHERE fieldname REGEXP 'pattern';
TÄSTÄ:
- ”SELECT-lauseke” on standardi SELECT-lause.
- "WHERE-kentän nimi" on sen sarakkeen nimi, jolle säännöllinen lauseke suoritetaan.
- "REGEXP-kuvio" — REGEXP on säännöllisen lausekkeen operaattori ja 'pattern' edustaa sovitettavaa kuviota. RLIKE on synonyymi sanalle REGEXP ja palauttaa samat tulokset. Jotta sitä ei sekoitettaisi LIKE-operaattoriin, on parempi käyttää REGEXP-operaattoria.
Katsotaanpa nyt käytännön esimerkkiä.
SELECT * FROM `movies` WHERE `title` REGEXP 'code';
Yllä oleva kysely etsii kaikkia elokuvien nimiä, jotka sisältävät sanan ”koodi”. Sillä ei ole väliä, esiintyykö ”koodi” nimikkeen alussa, keskellä vai lopussa. Niin kauan kuin nimi sisältää kuvion, rivi palautetaan.
Arvon alun yhteensovittaminen merkkiluettelon kanssa
Oletetaan, että haluamme elokuvat, joiden nimi alkaa kirjaimella a, b, c tai d, ja jota seuraa mikä tahansa määrä muita merkkejä. Yhdistämme merkkiluettelon ja sirkumfleksimetamerkin saavuttaaksemme tämän tuloksen.
SELECT * FROM `movies` WHERE `title` REGEXP '^[abcd]';
Suoritetaan yllä oleva komentosarja MySQL Työpöytä myflixdb-tietokantaa vasten antaa meille seuraavat tulokset.
| elokuvan_tunnus | otsikko | johtaja | vuosi_vapautettu | kategorian_tunnus |
|---|---|---|---|---|
| 4 | Code Nimi Musta | Edgar Jimz | 2010 | NULL |
| 5 | Isän pienet tytöt | NULL | 2007 | 8 |
| 6 | enkelit ja demonit | NULL | 2007 | 6 |
| 7 | DaVinci Code | NULL | 2007 | 6 |
Mallissa '^[abcd]' sirkumfleksi (^) vaatii, että osuma alkaa arvon alusta, ja merkkiluettelo [abcd] hyväksyy vain otsikot, joiden ensimmäinen kirjain on a, b, c tai d. Vertailu ei ole kirjainkoon suhteen merkitsevä oletuslajittelun aikana, minkä vuoksi ”Code Nimi Musta” palautetaan.
Merkkien poisjättäminen, jos merkkiluettelo on negatiivi
Muokataan nyt skriptiä ja negoidaan merkkiluettelo nähdäksemme, mitkä rivit palautetaan.
SELECT * FROM `movies` WHERE `title` REGEXP '^[^abcd]';
Suoritetaan yllä oleva komentosarja MySQL Workbenchin vertailu myflixdb-tietokantaa vasten antaa seuraavat tulokset.
| elokuvan_tunnus | otsikko | johtaja | vuosi_vapautettu | kategorian_tunnus |
|---|---|---|---|---|
| 1 | Pirates of the Caribbean 4 | Rob Marshall | 2011 | 1 |
| 2 | Sarah Marshal unohdetaan | Nicholas Stoller | 2008 | 2 |
| 3 | X-Men | 2008 | ||
| 9 | Honey mooners | John Schultz | 2005 | 8 |
| 16 | 67% syyllinen | 2012 | ||
| 17 | Diktaattori | Chalie Chaplie | 1920 | 7 |
| 18 | esimerkkielokuva | anonyymi | 8 | |
| 19 | elokuva 3 | John Brown | 1920 | 8 |
Merkkiluettelon sisällä sirkumfleksin merkitys muuttuu: '^[^abcd]' ankkuroi osuman edelleen alkuun, kun taas [^abcd] sulkee nyt pois kaikki otsikot, jotka alkavat jollakin luettelossa olevista merkeistä.
Näissä kahdessa esimerkissä käytetään vain ankkureita ja merkkiluetteloita. Seuraavassa osiossa käsitellään koko metamerkkijoukkoa.
Säännöllisen lausekkeen metamerkit
Yllä olevat esimerkit näyttävät säännöllisen lausekkeen yksinkertaisimman muodon. Metamerkkien avulla voit hienosäätää hahmohakua: ne ilmaisevat toistoa, vaihtoehtoja, alueita ja sijainteja. Alla olevassa taulukossa luetellaan kaikki säännöllisen lausekkeen tukemat metamerkit. MySQL REGEXP-operaattori, ja jokaisesta on korjattu esimerkki.
| Char | Tuotetiedot | esimerkki | |
|---|---|---|---|
| * | tähti (*) vastaa nollaa (0) tai useampaa esiintymää yksittäinen merkki joka sitä edeltää. | SELECT * FROM elokuvista WHERE nimi REGEXP 'da*'; vastaa kirjainta ”d”, jota seuraa nolla tai useampi ”a”-merkki, joten Da Vinci Code ja Daddy's Little Girls täyttävät vaatimukset. Käytä 'da+', kun kirjaimen "a" on oltava läsnä. | |
| + | lisää (+) vastaa yhtä tai useampaa esiintymää sitä edeltävää merkkiä. | SELECT * FROM `elokuvista` WHERE `nimi` REGEXP 'mon+'; antaa kaikki elokuvat, jotka sisältävät "mon"-sanan ja sen perässä yhden tai useamman "n"-kirjaimen. Esimerkiksi Enkelit ja demonit. | |
| ? | kysymysmerkki (?) vastaa nollaa (0) tai yhtä esiintymää sitä edeltävää merkkiä. | SELECT * FROM `categories` WHERE `kategorian_nimi` REGEXP 'com?'; vastaa sanaa ”co” ja valinnaista ”m”. Esimerkiksi komedia ja romanttinen komedia. | |
| . | piste (.) vastaa mitä tahansa yksittäistä merkkiä paitsi rivinvaihtoa. | SELECT * FROM elokuvista WHERE `year_released` REGEXP '200.'; näyttää kaikki tietyn vuoden aikana julkaistut elokuvat, jotka alkavat numerolla ”200” ja jota seuraa mikä tahansa yksittäinen hahmo. Esimerkiksi 2005, 2007, 2008. | |
| [Abc] | merkkiluettelo [abc] vastaa mitä tahansa suljetuista merkeistä. | SELECT * FROM `elokuvista` WHERE `nimi` REGEXP '[vwxyz]'; antaa kaikki elokuvat, joissa esiintyy yksikin hahmo joukosta ”vwxyz”. Esimerkiksi X-Men ja Da Vinci Code. | |
| [^ Abc] | negoitu lista [^abc] vastaa mitä tahansa merkkiä paitsi niiden sisällä olevia. | SELECT * FROM `elokuvista` WHERE `nimi` REGEXP '^[^vwxyz]'; näyttää kaikki elokuvat, joiden nimi ei ala "vwxyz"-alkuisessa merkissä. | |
| [AZ] | alue [AZ] vastaa mitä tahansa isoa kirjainta. | SELECT * FROM `jäsenet` WHERE `postiosoite` REGEXP '[AZ]'; antaa kaikille jäsenille, joiden postiosoitteessa on kirjain A:n ja Z:n välillä. Esimerkiksi Janet Jones, jonka jäsennumero on 1. | |
| [Az] | alue [az] vastaa mitä tahansa pientä kirjainta. | SELECT * FROM `jäsenet` WHERE `postiosoite` REGEXP '[az]'; antaa kaikille jäsenille, joiden postiosoitteessa on kirjain a:n ja z:n välillä. Huomaa, että oletusarvoinen lajittelu ei ole kirjainkokoherkkä, joten tämä väli vastaa myös isoja kirjaimia. | |
| [0-9] | alue [0–9] vastaa mitä tahansa numeroa väliltä 0–9. | SELECT * FROM `jäsenet` WHERE `yhteysnumero` REGEXP '[0-9]'; antaa kaikille jäsenille, joiden yhteystietonumerossa on vähintään yksi numero. Esimerkiksi Robert Phil. | |
| ^ | huolenpito (^) ankkuroi osuman arvon alkuun. | SELECT * FROM `elokuvista` WHERE `nimi` REGEXP '^[cd]'; antaa kaikki elokuvat, joiden nimi alkaa kirjaimella ”c” tai ”d”. Esimerkiksi Code Nimi Musta, Isän pienet tytöt ja Da Vinci Code. | |
| $ | dollarimerkki ($) ankkuroi osuman arvon loppuun. | SELECT * FROM `elokuvat` WHERE `otsikko` REGEXP 'koodi$'; antaa kaikki elokuvat, joiden nimi päättyy sanaan ”koodi”. Esimerkiksi Davinci Code. | |
| | | pystypalkki (|) eristää vaihtoehdot. | SELECT * FROM `elokuvista` WHERE `nimi` REGEXP '^[cd]|^[u]'; antaa kaikki elokuvat, joiden nimi alkaa kirjaimella ”c”, ”d” tai ”u”. Esimerkiksi Code Nimi Musta, Da Vinci Codeja Underworld – Awakenden. | |
| \b | sanaraja (\b) vastaa sanan alkua tai loppua. Se korvaa vanhemmat [[:<:]]- ja [[:>:]]-merkit, jotka MySQL 8.0 poistettu. | SELECT * FROM `elokuvat` WHERE `otsikko` REGEXP '\\bfor'; näyttää kaikki elokuvat, joiden sana alkaa sanalla ”for”. Esimerkiksi Forgetting Sarah Marshal. MySQL 5.7 vastaava malli on '[[:<:]]for'. | |
| [[:luokka:]] | hahmoluokka löytää nimetyn merkkiryhmän: [[:alpha:]] kirjaimille, [[:space:]] välilyönnille, [[:punct:]] välimerkeille ja [[:upper:]] isoille kirjaimille. Huomaa kaksinkertainen hakasulkeet. | SELECT * FROM `elokuvat` WHERE `otsikko` REGEXP '^[[:alpha:][:välilyönti:]]+$'; näyttää kaikki elokuvat, joiden nimessä on vain kirjaimia ja välilyöntejä. Esimerkiksi Forgetting Sarah Marshal, kun taas Pirates of the Caribean 4 jätetään pois numeron vuoksi. | |
Kenoviiva (\) on koodinvaihtomerkki. Koska MySQL jäsentää ensin merkkijonon ja sitten kuvion, literaali kenoviiva on kirjoitettava kaksoiskenoviivana (\\) säännöllisen lausekkeen kuvion sisällä.
⚠️ Versiovaroitus: MySQL Versiossa 8.0.4 vanha säännöllisten lausekkeiden moottori korvattiin ICU-kirjastolla. Sanamerkit [[:<:]] ja [[:>:]] poistettiin kyseisessä julkaisussa, joten vanhemmasta materiaalista kopioidut mallit epäonnistuvat "syntaksivirheellä" MySQL 8.0. Käytä sen sijaan \b-merkkiä.
Nyt kun jokainen metamerkki on määritelty, herää oikeutettu kysymys: milloin REGEXP:n tulisi korvata yksinkertaisempi LIKE-operaattori?
REGULAASI vs. TYKKÄÄ: kumpaa kannattaa käyttää?
Molemmat operaattorit suodattavat rivejä kuvion mukaan, mutta ne ratkaisevat eri ongelmia. LIKE ymmärtää vain kaksi symbolia, kun taas REGEXP ymmärtää yllä esitetyn koko metamerkkijoukon. Tällä teholla on hintansa, joten valinta on pikemminkin kompromissi kuin mieltymys.
| Kriteeri | LIKE | Säännöllinen lauseke |
|---|---|---|
| Kuviosymbolit | Vain % ja _ | Anchors, alueet, vuorottelu, kvanttorit, merkistöluokat |
| Tyypillinen käyttö | Etuliite-, jälkiliite- ja ”sisältää”-haut | Validointi, useita vaihtoehtoja, sijaintitietoinen yhteensovittaminen |
| Indeksin käyttö | Mahdollinen, kun kuvio ei ala merkillä % | Ei koskaan käytä indeksiä |
| Palautusarvo | TOSI vai EPÄTOSI | 1 tai 0 ja NULL, kun jompikumpi operandeista on NULL |
Valitse LIKE suoraviivaiseen vastaavuuteen, koska se lukee hyvin ja voi silti käyttää indeksiä. Valitse REGEXP, kun yhden mallin on ilmaistava useita sääntöjä kerralla, kuten "alkaa c:llä tai d:llä ja päättyy numeroon". Suurissa taulukoissa rajaa rivejä ensin indeksoidulla ehdolla ja käytä sitten REGEXP:iä tähän pienempään joukkoon.
MySQL 8.0 säännöllisten lausekkeiden funktiot
REGEXP-operaattori vastaa vain yhteen kysymykseen: vastaako arvo kuviota? MySQL 8.0 lisäsi neljä toimintoa, jotka menevät pidemmälle ja joiden avulla voit paikantaa esim.tract ja kirjoita vastaava teksti uudelleen. Jokainen hyväksyy valinnaisen match_type-argumentin, jossa 'c' pakottaa kirjainkoon huomioivan vertailun ja 'i' pakottaa kirjainkoon huomioivan vertailun.
- REGEXP_LIKE(lauseke, kuvio) palauttaa arvon 1, kun arvo vastaa kuviota. Se on REGEXP-operaattorin funktiomuoto, ja match_type-argumentti tekee kirjainkoon huomioivan eron.
- REGEXP_INSTR(lauseke, malli) palauttaa osuman ensimmäisen merkin sijainnin tai arvon 0, jos kuviota ei löydy.
- REGEXP_SUBSTR(lauseke, malli) palauttaa vastaavan alimerkkijonon itse, mikä on hyödyllistä vuoden, koodin tai numeron hakemiseen pidemmästä tekstiarvosta.
- REGEXP_REPLACE(lauseke, malli, korvaus) palauttaa arvon jokaisen korvatun osuman kohdalla, joten se voi puhdistaa datan joukon sisällä SQL UPDATE -kysely.
SELECT title, REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title FROM `movies` WHERE REGEXP_LIKE(title, '[0-9]');
Yllä oleva kysely palauttaa jokaisen elokuvan nimen, joka sisältää numeron, sekä itse numerot. MySQL 5.7 Nämä funktiot eivät ole käytettävissä, joten REGEXP-operaattori on edelleen ainoa vaihtoehto.

