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.
- «ГДЕ имя поля» — это имя столбца, к которому применяется регулярное выражение.
- «Шаблон REGEXP» — REGEXP — это оператор регулярных выражений, а 'pattern' обозначает шаблон, которому нужно соответствовать. 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 Верстак При обращении к базе данных myflixdb мы получаем следующие результаты.
| Movie_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 Возвращается сообщение "Name Black".
Исключение символов, список которых содержит отрицательные символы.
Теперь изменим скрипт и инвертируем список символов, чтобы посмотреть, какие строки будут возвращены.
SELECT * FROM `movies` WHERE `title` REGEXP '^[^abcd]';
Выполнение приведенного выше сценария в MySQL При использовании Workbench с базой данных myflixdb мы получаем следующие результаты.
| Movie_id | название | директор | год_выпущено | ид_категории |
|---|---|---|---|---|
| 1 | Пираты Карибского моря 4 | Роб Маршалл | 2011 | 1 |
| 2 | Забыть Сару Маршал | Николас Столлер | 2008 | 2 |
| 3 | X-Men | 2008 | ||
| 9 | Honey moonERS | Джон Шульц | 2005 | 8 |
| 16 | 67% Виновен | 2012 | ||
| 17 | Великий диктатор | Чали Чапли | 1920 | 7 |
| 18 | пример фильма | Anonymous | 8 | |
| 19 | фильм 3 | Джон Браун | 1920 | 8 |
Внутри списка символов значение символа "^[^abcd]" меняется: "^[^abcd]" по-прежнему указывает на начало совпадения, а "[^abcd]" теперь исключает все заголовки, начинающиеся с одного из заключенных в него символов.
В этих двух примерах используются только привязки и списки символов. В следующем разделе рассматривается полный набор метасимволов.
Метасимволы регулярных выражений
Приведенные выше примеры демонстрируют простейшую форму регулярного выражения. Метасимволы позволяют уточнить поиск по шаблону: они выражают повторение, альтернативы, диапазоны и позиции. В таблице ниже перечислены все метасимволы, поддерживаемые MySQL Оператор REGEXP с исправленным примером для каждого из них.
| Голец | Описание | Пример | |
|---|---|---|---|
| * | звездочка (*) соответствует нулю (0) или более экземплярам один символ что предшествует этому. | ВЫБРАТЬ * ИЗ фильмов ГДЕ заголовок REGEXP 'da*'; соответствует букве «d», за которой следует ноль или более символов «a», поэтому Да Винчи Code И папины маленькие девочки тоже подходят. Используйте 'da+', когда буква «a» обязательно должна присутствовать. | |
| + | плюс (+) соответствует одному или нескольким экземплярам предшествующего ему символа. | SELECT * FROM `movies` WHERE `title` REGEXP 'mon+'; Отображает все фильмы, содержащие слово «mon», за которым следует один или несколько символов «n». Например, «Ангелы и демоны». | |
| ? | вопросительный знак (?) соответствует нулю (0) или одному экземпляру предшествующего ему символа. | SELECT * FROM `categories` WHERE `category_name` REGEXP 'com?'; Сопоставляет «co» с необязательной «m». Например, комедия и романтическая комедия. | |
| . | точка (.) Соответствует любому отдельному символу, кроме символа новой строки. | ВЫБРАТЬ * ИЗ фильмов ГДЕ `year_released` REGEXP '200.'; Отображает все фильмы, вышедшие в год, начинающийся с «200», за которым следует любой отдельный символ. Например, 2005, 2007, 2008. | |
| [абв] | список символов [abc] соответствует любому из заключенных символов. | SELECT * FROM `movies` WHERE `title` REGEXP '[vwxyz]'; Отображает все фильмы, содержащие любого персонажа из «vwxyz». Например, «Люди Икс» и «Да Винчи». Code. | |
| [^ abc] | Отрицательный список [^abc] Соответствует любому символу, кроме заключенных в скобки. | SELECT * FROM `movies` WHERE `title` REGEXP '^[^vwxyz]'; Отображает все фильмы, название которых не начинается с символа из "vwxyz". | |
| [AZ] | диапазон [АЗ] соответствует любой заглавной букве. | SELECT * FROM `members` WHERE `postal_address` REGEXP '[AZ]'; Включает всех членов, в почтовом адресе которых содержится буква от А до Я. Например, Джанет Джонс с номером членства 1. | |
| [аз] | диапазон [аз] соответствует любой строчной букве. | SELECT * FROM `members` 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]'; Отображает все фильмы, название которых начинается с буквы «с» или «d». Например, Code Имя Блэк, «Папины маленькие девочки» и Да Винчи Code. | |
| $ | знак доллара ($) привязывает совпадение к концу значения. | SELECT * FROM `movies` WHERE `title` REGEXP 'code$'; Отображает все фильмы, название которых заканчивается на «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'; Отображает все фильмы, в названии которых есть слово, начинающееся на «for». Например, «Забывая Сару Маршал». MySQL 5.7 Эквивалентный шаблон — '[[:<:]]for'. | |
| [[:сорт:]] | класс персонажа соответствует именованной группе символов: [[:alpha:]] для букв, [[:space:]] для пробелов, [[:punct:]] для знаков препинания и [[:upper:]] для заглавных букв. Обратите внимание на двойной квадратных скобок. | SELECT * FROM `movies` WHERE `title` REGEXP '^[[:alpha:][:space:]]+$'; Отображает все фильмы, в названии которых содержатся только буквы и пробелы. Например, «Забывая Сару Маршал», тогда как «Пираты Карибского моря 4» исключены из-за наличия цифры. | |
Обратная косая черта (\) — это экранирующий символ. Потому что MySQL Сначала анализируется строка, а затем шаблон; обратная косая черта должна быть записана как двойная обратная косая черта (\\) внутри шаблона регулярного выражения.
⚠️ Предупреждение о версии: MySQL В версии 8.0.4 старый механизм регулярных выражений был заменен библиотекой ICU. В этом релизе были удалены маркеры слов [[:<:]] и [[:>:]], поэтому шаблоны, скопированные из более старых материалов, выдают ошибку синтаксиса. MySQL 8.0. Используйте \b вместо этого.
Теперь, когда определены все метасимволы, возникает закономерный вопрос: когда следует заменить более простой оператор LIKE оператором REGEXP?
Регулярные выражения или LIKE: какой из них лучше использовать?
Оба оператора фильтруют строки по шаблону, но решают разные задачи. Оператор LIKE распознает только два символа, в то время как REGEXP распознает полный набор метасимволов, показанный выше. Эта возможность имеет свою цену, поэтому выбор — это скорее компромисс, чем предпочтение.
| Критерий | LIKE | REGEXP |
|---|---|---|
| Символы узора | % и _ только | Anchors, диапазоны, чередование, кванторы, классы символов |
| Типичное использование | Поиск по префиксам, суффиксам и ключевому слову «содержит» | Проверка достоверности, несколько альтернатив, сопоставление с учетом положения. |
| Использование индекса | Возможно, если шаблон не начинается с % | Индекс никогда не используется |
| Возвращаемое значение | Правда или ложь | 1 или 0, и NULL, если хотя бы один из операндов равен NULL. |
Для простого сопоставления выбирайте LIKE, поскольку он хорошо читается и при этом позволяет использовать индекс. Используйте REGEXP, когда один шаблон должен выражать несколько правил одновременно, например, «начинается с c или d и заканчивается цифрой». В больших таблицах сначала сузьте строки с помощью условия с индексом, а затем примените REGEXP к этому меньшему набору.
MySQL 8.0 Функции регулярных выражений
Оператор REGEXP отвечает только на один вопрос: соответствует ли значение шаблону? MySQL В версии 8.0 добавлены четыре дополнительные функции, позволяющие, например, находитьtracи переписать совпадающий текст. Каждый из них принимает необязательный аргумент match_type, где 'c' обеспечивает сравнение с учетом регистра, а 'i' — без учета регистра.
- REGEXP_LIKE(expr, pattern) Возвращает 1, если значение соответствует шаблону. Это функциональная форма оператора REGEXP, а аргумент match_type явно указывает на чувствительность к регистру.
- REGEXP_INSTR(expr, pattern) Возвращает позицию первого символа совпадения или 0, если шаблон не найден.
- REGEXP_SUBSTR(expr, pattern) Возвращает саму совпадающую подстроку, что полезно для извлечения года, кода или числа из более длинного текстового значения.
- REGEXP_REPLACE(expr, pattern, replacement) возвращает значение с заменой каждого совпадения, что позволяет очищать данные внутри SQL-запрос на обновление.
SELECT title, REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title FROM `movies` WHERE REGEXP_LIKE(title, '[0-9]');
Приведённый выше запрос возвращает все названия фильмов, содержащие цифры, вместе с самими цифрами. MySQL 5.7 Эти функции недоступны, поэтому оператор REGEXP остается единственным вариантом.
