MySQL Регулярни изрази (Regexp)
⚡ Умно обобщение
MySQL Регулярните изрази (REGEXP) съпоставят стойностите на колоните с гъвкави шаблони, които заместващите символи не могат да изразят. Това обяснява синтаксиса на REGEXP, синонима RLIKE, всеки поддържан метасимвол, коригирани примери за заявки спрямо базата данни myflixdb и функциите за регулярни изрази, добавени в MySQL 8.0.
Какви са MySQL регулярни изрази?
MySQL редовни изрази ще ви помогнат да търсите данни, които отговарят на сложни критерии. Регулярният израз е шаблон, който описва формата на търсената стойност, а не самата стойност.
Ако вече сте работили с MySQL заместващи символи, може да се запитате защо си струва да се изучават регулярни изрази, когато LIKE дава подобни резултати. Отговорът е изразителната сила: заместващите символи предлагат само два символа, докато регулярните изрази описват диапазони от символи, алтернативи, повторения и позиции на думи в един шаблон.
След като целта е установена, следващият раздел представя синтаксиса, който ще използвате във всяка REGEXP заявка.
Основен синтаксис на REGEXP
Основният синтаксис на регулярен израз е следният.
SELECT * FROM table_name WHERE fieldname REGEXP 'pattern';
ТУК:
- „SELECT оператор“ е стандартът SELECT израз.
- „WHERE име на поле“ е името на колоната, върху която се изпълнява регулярният израз.
- „REGEXP „образец““ — REGEXP е операторът за регулярни изрази, а „шаблон“ представлява шаблона, който трябва да бъде съпоставен. RLIKE е синоним на REGEXP и връща същите резултати. За да избегнете объркването му с оператора LIKE, е по-добре да използвате REGEXP.
Нека сега разгледаме един практически пример.
SELECT * FROM `movies` WHERE `title` REGEXP 'code';
Горната заявка търси всички заглавия на филми, които съдържат думата „code“. Няма значение дали „code“ се появява в началото, в средата или в края на заглавието. Стига заглавието да съдържа шаблона, редът се връща.
Съпоставяне на началото на стойност със списък от символи
Да предположим, че искаме филмите, чиито заглавия започват с a, b, c или d, последвани от произволен брой други символи. Комбинираме списък със символи с метасимвола каретка, за да постигнем този резултат.
SELECT * FROM `movies` WHERE `title` REGEXP '^[abcd]';
Изпълнение на горния скрипт в MySQL Workbench спрямо базата данни myflixdb ни дава следните резултати.
| movie_id | заглавие | директор | year_released | категория_id |
|---|---|---|---|---|
| 4 | Code Име Черно | Едгар Джимз | 2010 | NULL |
| 5 | Малките момичета на татко | NULL | 2007 | 8 |
| 6 | Ангели и демони | NULL | 2007 | 6 |
| 7 | Да Винчи Code | NULL | 2007 | 6 |
В шаблона „^[abcd]“, каретката (^) изисква съвпадението да започва от началото на стойността, а списъкът със символи [abcd] приема само заглавия, чиято първа буква е a, b, c или d. Сравнението не е чувствително към главни и малки букви при подразбиращото се сравнение, поради което „Code Връща се „Име Блек“.
Изключване на символи със списък с отрицани символи
Нека сега модифицираме скрипта и да отменим списъка със символи, за да видим кои редове се връщат.
SELECT * FROM `movies` WHERE `title` REGEXP '^[^abcd]';
Изпълнение на горния скрипт в MySQL Workbench срещу базата данни myflixdb ни дава следните резултати.
| movie_id | заглавие | директор | year_released | категория_id |
|---|---|---|---|---|
| 1 | Карибски пирати 4 | Rob Marshall | 2011 | 1 |
| 2 | Забравяйки Сара Маршал | Николас Столер | 2008 | 2 |
| 3 | X-Men | 2008 | ||
| 9 | Honey moonERS | Джон Шулц | 2005 | 8 |
| 16 | 67% виновен | 2012 | ||
| 17 | Великият диктатор | Чали Чапли | 1920 | 7 |
| 18 | примерен филм | анонимен | 8 | |
| 19 | филм 3 | Джон Браун | 1920 | 8 |
В списък със символи, каретката променя значението си: '^[^abcd]' все още закотвя съвпадението в началото, докато [^abcd] вече изключва всяко заглавие, което започва с един от затворените символи.
Тези два примера използват само котви и списъци със символи. Следващият раздел обхваща пълния набор от метасимволи.
Метазнаци на регулярни изрази
Примерите по-горе показват най-простата форма на регулярен израз. Метасимволите ви позволяват да прецизирате търсенето по шаблон: те изразяват повторение, алтернативи, диапазони и позиции. Таблицата по-долу изброява всички метасимволи, поддържани от MySQL REGEXP оператор, с коригиран пример за всеки един.
| Овъглявам | Descriptйон | Пример | |
|---|---|---|---|
| * | - звездичка (*) съвпада с нула (0) или повече екземпляри на един символ което го предхожда. | SELECT * FROM филми WHERE заглавие REGEXP 'da*'; съвпада с „d“, последвано от нула или повече символа „a“, така че Да Винчи Code и „Daddy's Little Girls“ отговарят на условията. Използвайте „da+“, когато буквата „a“ действително трябва да присъства. | |
| + | - плюс (+) съвпада с един или повече екземпляри на символа, който го предхожда. | SELECT * FROM `movies` WHERE `title` REGEXP 'mon+'; Извежда всички филми, съдържащи „mon“, последвано от един или повече символа „n“. Например, Ангели и демони. | |
| ? | - въпросителен знак (?) съвпада с нула (0) или един екземпляр на символа, който го предхожда. | SELECT * FROM `categories` WHERE `category_name` REGEXP 'com?'; съвпада с „co“ с незадължително „m“. Например, комедия и романтична комедия. | |
| . | - точка (.) съвпада с всеки един символ, с изключение на нов ред. | SELECT * FROM филми WHERE `year_released` REGEXP '200.'; показва всички филми, издадени през една година, започващи с „200“, последвано от произволен символ. Например, 2005, 2007, 2008. | |
| [abc] | - списък със знаци [abc] съвпада с който и да е от затворените символи. | SELECT * FROM `movies` WHERE `title` REGEXP '[vwxyz]'; показва всички филми, съдържащи който и да е герой от „vwxyz“. Например Х-Мен и Да Винчи Code. | |
| [^abc] | - отрицателен списък [^abc] съвпада с всеки символ, освен тези, затворени в него. | SELECT * FROM `film` WHERE `title` REGEXP '^[^vwxyz]'; показва всички филми, чието заглавие не започва със символ от „vwxyz“. | |
| [AZ] | - диапазон [AZ] съвпада с всяка главна буква. | SELECT * FROM `членове` WHERE `postal_address` REGEXP '[AZ]'; дава всички членове, чийто пощенски адрес съдържа буква между A и Z. Например, Джанет Джоунс с номер на членство 1. | |
| [az] | - диапазон [az] съвпада с всяка малка буква. | SELECT * FROM `членове` WHERE `postal_address` REGEXP '[az]'; дава на всички членове, чийто пощенски адрес съдържа буква между a и z. Обърнете внимание, че сортирането по подразбиране е без значение от главните букви, така че този диапазон също съвпада с главни букви. | |
| [0-9] | - диапазон [0-9] съвпада с всяка цифра от 0 до 9. | SELECT * FROM `members` WHERE `contact_number` REGEXP '[0-9]'; дава всички членове, чийто телефонен номер съдържа поне една цифра. Например, Робърт Фил. | |
| ^ | - карета (^) закотвя съвпадението в началото на стойността. | SELECT * FROM `movies` WHERE `title` REGEXP '^[cd]'; дава всички филми, чието заглавие започва с „c“ или „d“. Например Code Назовете Блек, малките момиченца на татко и Да Винчи Code. | |
| $ | - знак за долар ($) закотвя съвпадението в края на стойността. | SELECT * FROM `movies` WHERE `title` REGEXP 'code$'; дава всички филми, чието заглавие завършва с „код“. Например, Да Винчи Code. | |
| | | - вертикална лента (|) изолира алтернативите. | SELECT * FROM `movies` WHERE `title` REGEXP '^[cd]|^[u]'; показва всички филми, чието заглавие започва с „c“, „d“ или „u“. Например Code Име Блек, Да Винчи Codeи Подземния свят – AwakenING. | |
| \b | - граница на думата (\b) съвпада с началото или края на думата. Той замества по-старите маркери [[:<:]] и [[:>:]], които MySQL 8.0 е премахнато. | SELECT * FROM `movies` WHERE `title` REGEXP '\\bfor'; дава всички филми с дума, започваща с „за“. Например, „Забравяйки Сара Маршал“. На MySQL 5.7 еквивалентният шаблон е '[[:<:]]for'. | |
| [[:клас:]] | - клас символи съвпада с именувана група от символи: [[:alpha:]] за букви, [[:space:]] за интервали, [[:punct:]] за препинателни знаци и [[:upper:]] за главни букви. Обърнете внимание на удвои квадратни скоби. | SELECT * FROM `movies` WHERE `title` REGEXP '^[[:alpha:][:space:]]+$'; показва всички филми, чието заглавие съдържа само букви и интервали. Например, „Забравяйки Сара Маршал“, докато „Карибски пирати 4“ е пропуснат заради цифрата. | |
Обратната наклонена черта (\) е символът за изход. Защото MySQL анализира първо низа, а след това шаблона, буквалната обратна наклонена черта трябва да бъде записана като двойна обратна наклонена черта (\\) вътре в REGEXP шаблон.
⚠️ Предупреждение за версията: MySQL Версия 8.0.4 замени стария механизъм за регулярни изрази с библиотеката ICU. Маркерите за думи [[:<:]] и [[:>:]] бяха премахнати в тази версия, така че шаблоните, копирани от по-стар материал, се провалят с „синтактична грешка“ на MySQL 8.0. Използвайте \b вместо това.
След като всеки метасимвол е дефиниран, следва справедлив въпрос: кога REGEXP трябва да замени по-простия оператор LIKE?
REGEXP срещу LIKE: кой да използвате?
И двата оператора филтрират редове по шаблон, но решават различни проблеми. LIKE разбира само два символа, докато REGEXP разбира пълния набор от метасимволи, показан по-горе. Тази възможност си има цена, така че изборът е по-скоро компромис, отколкото предпочитание.
| критерий | КАТО | РЕГУЛЯРЕН ИЗРАЗ |
|---|---|---|
| Символи на шарки | само % и _ | Anchors, диапазони, редуване, квантификатори, класове символи |
| Типична употреба | Търсения по префикс, суфикс и „съдържа“ | Валидиране, множество алтернативи, съпоставяне въз основа на позицията |
| Използване на индекса | Възможно е, когато шаблонът не започва с % | Никога не използва индекс |
| Върната стойност | ВЯРНО или НЕВЯРНО | 1 или 0 и NULL, когато някой от операндите е NULL |
Изберете LIKE за лесно съвпадение, защото се чете добре и все още може да използва индекс. Изберете REGEXP, когато един шаблон трябва да изразява няколко правила едновременно, например „започва с c или d и завършва с цифра“. В големи таблици първо стеснете редовете с индексирано условие, след което приложете REGEXP към по-малкия набор.
MySQL 8.0 функции за регулярни изрази
Операторът REGEXP отговаря само на един въпрос: съответства ли стойността на шаблона? MySQL 8.0 добави четири функции, които отиват по-далеч и ви позволяват да локализирате, напр.tract и пренапишете съответстващия текст. Всеки от тях приема опционален аргумент match_type, където 'c' налага сравнение с чувствителност към главни и малки букви, а 'i' налага сравнение без чувствителност към главни и малки букви.
- REGEXP_LIKE(израз, шаблон) връща 1, когато стойността съвпада с шаблона. Това е функционалната форма на оператора REGEXP, а аргументът match_type прави чувствителността към главни и малки букви изрична.
- REGEXP_INSTR(израз, шаблон) връща позицията на първия символ от съвпадението или 0, когато шаблонът не е намерен.
- REGEXP_SUBSTR(израз, шаблон) връща самия съответстващ подниз, което е полезно за извличане на година, код или число от по-дълга текстова стойност.
- REGEXP_REPLACE(израз, шаблон, заместване) връща стойността с всяко заменено съвпадение, така че може да почисти данните вътре в SQL заявка за актуализиране.
SELECT title, REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title FROM `movies` WHERE REGEXP_LIKE(title, '[0-9]');
Горната заявка връща всяко заглавие на филм, което съдържа цифра, заедно със самите цифри. MySQL 5.7 тези функции не са налични, така че операторът REGEXP остава единствената опция.

