MySQL Regulární výrazy (Regexp)

⚡ Chytré shrnutí

MySQL Regulární výrazy (REGEXP) porovnávají hodnoty sloupců s flexibilními vzory, které zástupné znaky nemohou vyjádřit. Zde je vysvětlena syntaxe REGEXP, synonymum RLIKE, všechny podporované metaznaky, opravené příklady dotazů v databázi myflixdb a funkce regulárních výrazů přidané v MySQL 8.0.

  • 🔍 Jádro Operator: Funkce REGEXP porovnává sloupec se vzorem a v případě shody vrací hodnotu 1, zatímco RLIKE je přesným synonymem funkce REGEXP.
  • 🧩 Vzor Anchors: Stříška (^) ukotví shodu na začátek hodnoty a znak dolaru ($) ji ukotví na konec.
  • 🔤 Seznamy postav: [abcd] odpovídá libovolnému uzavřenému znaku a [^abcd] vylučuje všechny uzavřené znaky z výsledné sady.
  • Kvantifikátory: Hvězdička, znaménko plus a otazník se vztahují na jeden znak, který jim předchází, nikoli na celý řetězec.
  • 🛡️ Escaping Pravidlo: Doslovné zpětné lomítko se musí uvnitř vzoru zdvojnásobit, protože MySQL zpracuje řetězec dvakrát.
  • 🆕 Změna verze: MySQL Verze 8.0 se přesunula do enginu ICU, nahradila [[:<:]] a [[:>:]] řetězcem \b a přidala REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR a REGEXP_INSTR.
  • Poznámka k výkonu: Funkce REGEXP nikdy nepoužívá index, proto vždy, když to dotaz umožňuje, filtruje nejprve řádky s indexovanou podmínkou.

Jaké jsou MySQL regulární výrazy?

MySQL regulární výrazy vám pomohou vyhledat data, která odpovídají složitým kritériím. Regulární výraz je vzor, ​​který popisuje tvar hledané hodnoty, nikoli samotnou hodnotu.

Pokud jste již s MySQL zástupné znakyMožná se ptáte, proč se regulární výrazy vyplatí učit, když LIKE dává podobné výsledky. Odpovědí je expresivní síla: zástupné znaky nabízejí pouze dva symboly, zatímco regulární výrazy popisují rozsahy znaků, alternativy, opakování a pozice slov v jednom vzoru.

Po stanovení účelu se v následující části seznámíme s syntaxí, kterou budete používat v každém dotazu REGEXP.

Základní syntaxe REGEXP

Základní syntaxe regulárního výrazu je následující.

SELECT * FROM table_name
WHERE fieldname REGEXP 'pattern';

ZDE:

  • „Příkaz SELECT“ je standard příkaz SELECT.
  • "KDE název pole" je název sloupce, na kterém se provádí regulární výraz.
  • "Vzor REGEXP" — REGEXP je operátor regulárního výrazu a „pattern“ představuje vzor, ​​který má být nalezen. RLIKE je synonymum pro REGEXP a vrací stejné výsledky. Abyste se vyhnuli záměně s operátorem LIKE, je lepší použít REGEXP.

Podívejme se nyní na praktický příklad.

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

Výše uvedený dotaz vyhledává všechny názvy filmů, které obsahují slovo „code“. Nezáleží na tom, zda se slovo „code“ objevuje na začátku, uprostřed nebo na konci názvu. Pokud název obsahuje daný vzor, ​​je vrácen řádek.

Porovnání začátku hodnoty se seznamem znaků

Předpokládejme, že chceme filmy, jejichž názvy začínají písmeny a, b, c nebo d, za nimiž následuje libovolný počet dalších znaků. Tohoto výsledku dosáhneme kombinací seznamu znaků s metaznakem stříška.

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

Spuštění výše uvedeného skriptu v MySQL Workbench s databází myflixdb nám dává následující výsledky.

movie_id titul ředitel rok_vydáno category_id
4 Code Jméno Černá Edgar Jimz 2010 NULL
5 Tatínkovy holčičky NULL 2007 8
6 andělé a démoni NULL 2007 6
7 Davinci Code NULL 2007 6

Ve vzoru '^[abcd]' vyžaduje stříška (^) shodu na začátku hodnoty a seznam znaků [abcd] akceptuje pouze názvy, jejichž první písmeno je a, b, c nebo d. Porovnání při výchozím řazení nerozlišuje velká a malá písmena, a proto „Code Vrátí se „jméno Black“.

Vyloučení znaků se seznamem negovaných znaků

Nyní upravme skript a negatujme seznam znaků, abychom zjistili, které řádky se vrátí.

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

Spuštění výše uvedeného skriptu v MySQL Workbench s databází myflixdb nám dává následující výsledky.

movie_id titul ředitel rok_vydáno category_id
1 Piráti z Karibiku 4 Rob Marshall 2011 1
2 Zapomínání na Sarah Marshal Nicholas Stoller 2008 2
3 X-Men 2008
9 Honey mooneRS John Schultz 2005 8
16 67% vinen 2012
17 Diktátor Chalie Chaplie 1920 7
18 ukázkový film Anonymní 8
19 film 3 John Brown 1920 8

Uvnitř seznamu znaků se význam stříšky změní: '^[^abcd]' stále ukotví shodu na začátku, zatímco [^abcd] nyní vylučuje všechny názvy, které začínají jedním z uzavřených znaků.

Tyto dva příklady používají pouze kotvy a seznamy znaků. Následující část se zabývá celou sadou metaznaků.

Metaznaky regulárních výrazů

Výše uvedené příklady ukazují nejjednodušší formu regulárního výrazu. Metaznaky umožňují doladit vyhledávání podle vzoru: vyjadřují opakování, alternativy, rozsahy a pozice. V tabulce níže jsou uvedeny všechny metaznaky podporované regulárním výrazem. MySQL Operátor REGEXP s opraveným příkladem pro každý z nich.

Char Description Příklad
* Jedno hvězdička (*) shoduje se s nulou (0) nebo více instancemi jediná postava která tomu předchází. SELECT * Z filmů WHERE název REGEXP 'da*'; odpovídá písmenu „d“ následovanému nulou nebo více znaky „a“, takže Da Vinci Code a Daddy's Little Girls se kvalifikují. Použijte 'da+', když musí být skutečně přítomno písmeno „a“.
+ Jedno více (+) odpovídá jednomu nebo více výskytům znaku, který mu předchází. SELECT * FROM `filmy` WHERE `title` REGEXP 'mon+'; zobrazí všechny filmy obsahující slovo „mon“ následované jedním nebo více znaky „n“. Například Andělé a démoni.
? Jedno otazník (?) odpovídá nule (0) nebo jednomu výskytu znaku, který mu předchází. SELECT * FROM `categories` WHERE `category_name` REGEXP 'com?'; shoduje se s „co“ a volitelným „m“. Například komedie a romantická komedie.
. Jedno tečka (.) odpovídá libovolnému jednotlivému znaku kromě nového řádku. SELECT * FROM movies WHERE `year_released` REGEXP '200.'; uvádí všechny filmy vydané v daném roce začínající písmenem „200“ následovaným libovolným jednotlivým znakem. Například 2005, 2007, 2008.
[abc] Jedno seznam znaků [abc] odpovídá kterémukoli z uzavřených znaků. SELECT * FROM `filmy` WHERE `title` REGEXP '[vwxyz]'; uvádí všechny filmy obsahující libovolnou postavu z „vwxyz“. Například X-Men a Da Vinci Code.
[^abc] Jedno negovaný seznam [^abc] odpovídá libovolnému znaku kromě těch, které jsou v něm uvedeny. SELECT * FROM `filmy` WHERE `title` REGEXP '^[^vwxyz]'; uvádí všechny filmy, jejichž název nezačíná znakem ve slově „vwxyz“.
[AZ] Jedno rozsah [AZ] odpovídá libovolnému velkému písmenu. SELECT * FROM `členové` WHERE `poštovní_adresa` REGEXP '[AZ]'; zobrazí všechny členy, jejichž poštovní adresa obsahuje písmeno mezi A a Z. Například Janet Jones s číslem členství 1.
[az] Jedno rozsah [az] odpovídá libovolnému malému písmenu. SELECT * FROM `členové` WHERE `poštovní_adresa` REGEXP '[az]'; vrátí všechny členy, jejichž poštovní adresa obsahuje písmeno mezi a a z. Všimněte si, že výchozí řazení nerozlišuje velká a malá písmena, takže tento rozsah odpovídá i velkým písmenům.
[0-9] Jedno rozsah [0-9] odpovídá jakékoli číslici od 0 do 9. SELECT * FROM `členové` WHERE `kontaktní_číslo` REGEXP '[0-9]'; zobrazí všechny členy, jejichž kontaktní číslo obsahuje alespoň jednu číslici. Například Robert Phil.
^ Jedno stříška (^) ukotví shodu na začátek hodnoty. SELECT * FROM `filmy` WHERE `title` REGEXP '^[cd]'; zobrazí všechny filmy, jejichž název začíná na „c“ nebo „d“. Například Code Jméno Black, Daddy's Little Girls a Da Vinci Code.
$ Jedno znak dolaru ($) ukotví shodu na konci hodnoty. SELECT * FROM `filmy` WHERE `titul` REGEXP 'kód$'; uvádí všechny filmy, jejichž název končí na „code“. Například Da Vinci Code.
| Jedno svislý pruh (|) izoluje alternativy. SELECT * FROM `filmy` WHERE `title` REGEXP '^[cd]|^[u]'; zobrazí všechny filmy, jejichž název začíná písmenem „c“, „d“ nebo „u“. Například Code Jméno Black, Da Vinci Codea Podsvětí – AwakenIng.
\b Jedno hranice slova (\b) odpovídá začátku nebo konci slova. Nahrazuje starší značky [[:<:]] a [[:>:]], které MySQL 8.0 odstraněno. SELECT * FROM `filmy` WHERE `titul` REGEXP '\\bpro'; uvádí všechny filmy se slovem začínajícím na „pro“. Například Zapomeňme na Sarah Marshalovou. Na MySQL 5.7 ekvivalentní vzor je '[[:<:]]pro'.
[[:třída:]] Jedno třída postavy odpovídá pojmenované skupině znaků: [[:alpha:]] pro písmena, [[:space:]] pro mezery, [[:punct:]] pro interpunkci a [[:upper:]] pro velká písmena. Všimněte si zdvojnásobit hranaté závorky. SELECT * FROM `filmy` WHERE `titul` REGEXP '^[[:alpha:][:space:]]+$'; uvádí všechny filmy, jejichž název obsahuje pouze písmena a mezery. Například Zapomeňme na Sarah Marshalovou, zatímco Piráti z Karibiku 4 je vynechán kvůli číslici.

Zpětné lomítko (\) je řídicí znak. Protože MySQL Nejprve analyzuje řetězec a poté vzor, ​​doslovné zpětné lomítko musí být uvnitř vzoru REGEXP zapsáno jako dvojité zpětné lomítko (\\).

⚠️ Upozornění na verzi: MySQL Verze 8.0.4 nahradila starý engine regulárních výrazů knihovnou ICU. Značky slov [[:<:]] a [[:>:]] byly v této verzi odstraněny, takže vzory zkopírované ze staršího materiálu selhávají s chybou „syntaxe error“ na MySQL 8.0. Použijte místo toho \b.

Nyní, když jsou definovány všechny metaznaky, vyvstává oprávněná otázka: kdy by měl REGEXP nahradit jednodušší operátor LIKE?

REGEXP vs. LIKE: který z nich byste měli použít?

Oba operátory filtrují řádky podle vzoru, ale řeší různé problémy. LIKE rozumí pouze dvěma symbolům, zatímco REGEXP rozumí celé sadě metaznaků uvedené výše. Tato schopnost má svou cenu, takže volba je spíše kompromisem než preferencí.

Kritérium LIKE REGELEXP
Symboly vzorů pouze % a _ Anchors, rozsahy, alternace, kvantifikátory, třídy znaků
Typické použití Vyhledávání předpon, přípon a „obsahuje“ Validace, více alternativ, porovnávání s ohledem na polohu
Využití indexu Možné, pokud vzor nezačíná znakem %. Nikdy nepoužívá index
Návratová hodnota PRAVDA nebo NEPRAVDA 1 nebo 0 a NULL, pokud je kterýkoli z operandů NULL

Pro přímočaré porovnávání zvolte LIKE, protože se dobře čte a stále může používat index. REGEXP zvolte, pokud jeden vzor musí vyjadřovat několik pravidel najednou, například „začíná na c nebo d a končí číslicí“. U velkých tabulek nejprve zúžte řádky pomocí indexované podmínky a poté na tuto menší množinu použijte REGEXP.

MySQL Funkce regulárních výrazů 8.0

Operátor REGEXP odpovídá pouze na jednu otázku: odpovídá hodnota vzoru? MySQL Verze 8.0 přidala čtyři funkce, které jdou ještě dále a umožňují vám lokalizovat, např.tract a přepište odpovídající text. Každý z nich přijímá volitelný argument match_type, kde 'c' vynutí porovnání s rozlišováním velkých a malých písmen a 'i' vynutí porovnání bez rozlišování velkých a malých písmen.

  • REGEXP_LIKE(výraz, vzor) Vrací 1, pokud hodnota odpovídá vzoru. Jedná se o funkční formu operátoru REGEXP a argument match_type explicitně rozlišuje velká a malá písmena.
  • REGEXP_INSTR(výraz, vzor) vrací pozici prvního znaku shody nebo 0, pokud vzor není nalezen.
  • REGEXP_SUBSTR(výraz, vzor) vrací samotný odpovídající podřetězec, což je užitečné pro vytažení roku, kódu nebo čísla z delší textové hodnoty.
  • REGEXP_REPLACE(výraz, vzor, ​​nahrazení) vrací hodnotu s každou nahrazenou shodou, takže může vyčistit data uvnitř SQL aktualizační dotaz.
SELECT title,
       REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title
FROM `movies`
WHERE REGEXP_LIKE(title, '[0-9]');

Výše uvedený dotaz vrací všechny názvy filmů, které obsahují číslici, spolu s těmito číslicemi samotnými. MySQL 5.7 tyto funkce nejsou k dispozici, takže operátor REGEXP zůstává jedinou možností.

Nejčastější dotazy

Ve výchozím nastavení ne. Funkce REGEXP se řídí řazením sloupce a standardní řazení nerozlišuje velká a malá písmena. Pro vynucení porovnávání s rozlišením velkých a malých písmen přidejte před sloupec klíčové slovo BINARY nebo zavolejte funkci REGEXP_LIKE s typem shody 'c'.

Neexistuje žádný funkční rozdíl. RLIKE je synonymum pro REGEXP, které MySQL zachovává se kvůli kompatibilitě. V praxi se preferuje REGEXP, protože RLIKE se snadno zaměňuje s nesouvisejícím Operátor LIKE používá se pro zástupné znaky.

REGEXP nemůže použít index, takže MySQL vyhodnocuje vzor řádek po řádku. Nejprve zredukujte naskenované řádky pomocí indexované podmínky, rozsahu dat nebo fulltextového indexu a na tuto menší sadu výsledků použijte regulární výraz.

Ano. Asistenti umělé inteligence převádějí pravidlo v prostém jazyce na vzor REGEXP a vysvětlují každý metaznak. Otestujte výsledek v MySQL Workbench proti vzorovým řádkům, protože jediná chybně umístěná kotva změní celou sadu výsledků.

Ano. Asistenti s umělou inteligencí generují příkazy REGEXP_REPLACE, které odstraňují interpunkci, normalizují telefonní čísla nebo ořezávají mezery. Nejprve spusťte vzor uvnitř příkazu SELECT, potvrďte přepsané hodnoty a teprve poté jej použijte v… AKTUALIZOVAT prohlášení.

Shrňte tento příspěvek takto: