MySQL Регулярни изрази (Regexp)

⚡ Умно обобщение

MySQL Регулярните изрази (REGEXP) съпоставят стойностите на колоните с гъвкави шаблони, които заместващите символи не могат да изразят. Това обяснява синтаксиса на REGEXP, синонима RLIKE, всеки поддържан метасимвол, коригирани примери за заявки спрямо базата данни myflixdb и функциите за регулярни изрази, добавени в MySQL 8.0.

  • 🔍 Ядро OperaТор: REGEXP сравнява колона с шаблон и връща 1 за съвпадение, докато RLIKE е точен синоним на REGEXP.
  • 🧩 Модел Anchors: Каретката (^) закотвя съвпадението в началото на стойността, а знакът за долар ($) го закотвя в края.
  • 🔤 Списъци с герои: [abcd] съвпада с всеки затворен символ, а [^abcd] изключва всеки затворен символ от резултатния набор.
  • ➕ Квантори: Звездичката, плюсът и въпросителният знак се отнасят за единичния символ, който ги предхожда, а не за целия низ.
  • ️ Escaping правило: Обратната наклонена черта трябва да се удвои в шаблон, защото MySQL обработва низа два пъти.
  • 🆕 Промяна на версията: MySQL 8.0 е преместен в двигателя на ICU, заменя [[:<:]] и [[:>:]] с \b и добавя REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR и REGEXP_INSTR.
  • ⚡ Бележка за ефективността: REGEXP никога не използва индекс, така че филтрирайте редовете с индексирано условие първо, когато заявката го позволява.

Какви са 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 остава единствената опция.

Въпроси и Отговори

Не е по подразбиране. REGEXP следва сравнението на колоната, а стандартните сравнения са без значение от главни и малки букви. Добавете ключовата дума BINARY преди колоната или извикайте REGEXP_LIKE с типа съвпадение „c“, за да наложите сравнение, което да е чувствително към главни и малки букви.

Няма функционална разлика. RLIKE е синоним на REGEXP, който MySQL запазва се за съвместимост. REGEXP е предпочитан на практика, защото RLIKE лесно се бърка с несвързаното Оператор LIKE използва се за заместващи символи.

REGEXP не може да използва индекс, така че MySQL оценява шаблона ред по ред. Първо редуцирайте сканираните редове с индексирано условие, диапазон от дати или пълнотекстов индекс и приложете регулярния израз към този по-малък набор от резултати.

Да. Асистентите с изкуствен интелект преобразуват правило на разбираем език в REGEXP шаблон и обясняват всеки метасимвол. Тествайте резултата в MySQL Workbench спрямо примерни редове, защото една-единствена неправилно поставена котва променя целия набор от резултати.

Да. Асистентите с изкуствен интелект генерират REGEXP_REPLACE изрази, които премахват пунктуационните знаци, нормализират телефонните номера или изрязват излишни интервали. Първо изпълнете шаблона в SELECT, потвърдете пренаписаните стойности и едва след това го приложете в Изявление UPDATE.

Обобщете тази публикация с: