Обзор регулярных выражений
Регулярные выражения позволяют MariaDB выполнять сложный поиск шаблонов в строке. Во многих случаях достаточно простого поиска шаблонов с помощью LIKE. LIKE выполняет два типа сопоставлений:
-
_- символ нижнего подчеркивания, сопоставляющий один символ -
%- символ процента, сопоставляющий любое количество символов.
В других случаях вам может потребоваться больший контроль над возвращаемыми совпадениями, и вам потребуется использовать регулярные выражения.
До MariaDB 10.0.5 MariaDB использовала библиотеку регулярных выражений, совместимую с POSIX 1003.2. Новая библиотека PCRE в основном совместима со старой - см. статью PCRE Regular Expressions для получения информации об усовершенствованиях, внесенных в версии 10.0.5.
Сопоставления с регулярными выражениями выполняются с помощью функции REGEXP. RLIKE является синонимом для REGEXP.
Сравнения выполняются по значению байта, поэтому символы, которые считаются эквивалентными с учетом сортировки, но не имеют одинакового значения байта, например, символы с диакритическими знаками, могут оцениваться как неравные.
Без специальных символов сопоставление с регулярным выражением истинно, если символы совпадают. Сопоставление нечувствительно к регистру, за исключением случаев с бинарными строками.
SELECT 'Maria' REGEXP 'Maria'; +------------------------+ | 'Maria' REGEXP 'Maria' | +------------------------+ | 1 | +------------------------+ SELECT 'Maria' REGEXP 'maria'; +------------------------+ | 'Maria' REGEXP 'maria' | +------------------------+ | 1 | +------------------------+ SELECT BINARY 'Maria' REGEXP 'maria'; +-------------------------------+ | BINARY 'Maria' REGEXP 'maria' | +-------------------------------+ | 0 | +-------------------------------+
Обратите внимание, что сопоставляемое слово должно соответствовать всему шаблону:
SELECT 'Maria' REGEXP 'Mari'; +-----------------------+ | 'Maria' REGEXP 'Mari' | +-----------------------+ | 1 | +-----------------------+ SELECT 'Mari' REGEXP 'Maria'; +-----------------------+ | 'Mari' REGEXP 'Maria' | +-----------------------+ | 0 | +-----------------------+
В первом случае возвращается true, потому что шаблон «Mari» присутствует в выражении «Maria». При обратном порядке результат ложный, так как шаблон «Maria» не присутствует в выражении «Mari».
Сопоставление может выполняться с несколькими словами с помощью символа |. Например:
SELECT 'Maria' REGEXP 'Monty|Maria'; +------------------------------+ | 'Maria' REGEXP 'Monty|Maria' | +------------------------------+ | 1 | +------------------------------+
Специальные символы
Приведённые выше примеры демонстрируют синтаксис, но не очень полезны сами по себе. Именно специальные символы придают регулярным выражениям их мощь.
^
^ соответствует началу строки (в квадратных скобках это также может означать НЕ - см. ниже):
SELECT 'Maria' REGEXP '^Ma'; +----------------------+ | 'Maria' REGEXP '^Ma' | +----------------------+ | 1 | +----------------------+
$
$ соответствует концу строки:
SELECT 'Maria' REGEXP 'ia$'; +----------------------+ | 'Maria' REGEXP 'ia$' | +----------------------+ | 1 | +----------------------+
.
. соответствует любому одиночному символу:
SELECT 'Maria' REGEXP 'Ma.ia'; +------------------------+ | 'Maria' REGEXP 'Ma.ia' | +------------------------+ | 1 | +------------------------+ SELECT 'Maria' REGEXP 'Ma..ia'; +-------------------------+ | 'Maria' REGEXP 'Ma..ia' | +-------------------------+ | 0 | +-------------------------+
*
x* соответствует нулю или более экземплярам символа x. В примерах ниже это символ r.
SELECT 'Maria' REGEXP 'Mar*ia'; +-------------------------+ | 'Maria' REGEXP 'Mar*ia' | +-------------------------+ | 1 | +-------------------------+ SELECT 'Maia' REGEXP 'Mar*ia'; +------------------------+ | 'Maia' REGEXP 'Mar*ia' | +------------------------+ | 1 | +------------------------+ SELECT 'Marrria' REGEXP 'Mar*ia'; +---------------------------+ | 'Marrria' REGEXP 'Mar*ia' | +---------------------------+ | 1 | +---------------------------+
+
x+ соответствует одному или более экземплярам символа x. В примерах ниже это символ r.
SELECT 'Maria' REGEXP 'Mar+ia'; +-------------------------+ | 'Maria' REGEXP 'Mar+ia' | +-------------------------+ | 1 | +-------------------------+ SELECT 'Maia' REGEXP 'Mar+ia'; +------------------------+ | 'Maia' REGEXP 'Mar+ia' | +------------------------+ | 0 | +------------------------+ SELECT 'Marrria' REGEXP 'Mar+ia'; +---------------------------+ | 'Marrria' REGEXP 'Mar+ia' | +---------------------------+ | 1 | +---------------------------+
?
x? соответствует нулю или одному экземпляру символа x. В примерах ниже это символ r.
SELECT 'Maria' REGEXP 'Mar?ia'; +-------------------------+ | 'Maria' REGEXP 'Mar?ia' | +-------------------------+ | 1 | +-------------------------+ SELECT 'Maia' REGEXP 'Mar?ia'; +------------------------+ | 'Maia' REGEXP 'Mar?ia' | +------------------------+ | 1 | +------------------------+ SELECT 'Marrria' REGEXP 'Mar?ia'; +---------------------------+ | 'Marrria' REGEXP 'Mar?ia' | +---------------------------+ | 0 | +---------------------------+
()
(xyz) - объединяет последовательность, например (xyz)+ или (xyz)*
SELECT 'Maria' REGEXP '(ari)+'; +-------------------------+ | 'Maria' REGEXP '(ari)+' | +-------------------------+ | 1 | +-------------------------+
{}
x{n} и x{m,n} Этот символ используется для сопоставления множества экземпляров x. В случае x{n} сопоставление должно происходить ровно столько раз. В случае x{m,n}, сопоставление может происходить от m до n раз. Например, для сопоставления нуля или одного экземпляра строки ari (что идентично (ari)?), можно использовать следующее:
SELECT 'Maria' REGEXP '(ari){0,1}';
+-----------------------------+
| 'Maria' REGEXP '(ari){0,1}' |
+-----------------------------+
| 1 |
+-----------------------------+
[]
[xy] группирует символы для целей сопоставления. Например, для сопоставления либо символа p, либо символа r:
SELECT 'Maria' REGEXP 'Ma[pr]ia'; +---------------------------+ | 'Maria' REGEXP 'Ma[pr]ia' | +---------------------------+ | 1 | +---------------------------+
Квадратные скобки также позволяют указывать диапазон символов, например, для сопоставления любого символа от a до z используется [a-z]. Допускаются и числовые диапазоны.
SELECT 'Maria' REGEXP 'Ma[a-z]ia'; +----------------------------+ | 'Maria' REGEXP 'Ma[a-z]ia' | +----------------------------+ | 1 | +----------------------------+
Следующее не соответствует, так как r выходит за рамки диапазона a-p.
SELECT 'Maria' REGEXP 'Ma[a-p]ia'; +----------------------------+ | 'Maria' REGEXP 'Ma[a-p]ia' | +----------------------------+ | 0 | +----------------------------+
^
Символ ^ означает NOT совпадают, например:
SELECT 'Maria' REGEXP 'Ma[^p]ia'; +---------------------------+ | 'Maria' REGEXP 'Ma[^p]ia' | +---------------------------+ | 1 | +---------------------------+ SELECT 'Maria' REGEXP 'Ma[^r]ia'; +---------------------------+ | 'Maria' REGEXP 'Ma[^r]ia' | +---------------------------+ | 0 | +---------------------------+
Символы [ и ] сами по себе могут быть буквально сопоставлены внутри блока [] без экранирования, если они непосредственно следуют за открывающей скобкой:
SELECT '[Maria' REGEXP '[[]'; +-----------------------+ | '[Maria' REGEXP '[[]' | +-----------------------+ | 1 | +-----------------------+ SELECT '[Maria' REGEXP '[]]'; +-----------------------+ | '[Maria' REGEXP '[]]' | +-----------------------+ | 0 | +-----------------------+ SELECT ']Maria' REGEXP '[]]'; +-----------------------+ | ']Maria' REGEXP '[]]' | +-----------------------+ | 1 | +-----------------------+ SELECT ']Maria' REGEXP '[]a]'; +------------------------+ | ']Maria' REGEXP '[]a]' | +------------------------+ | 1 | +------------------------+
Неправильный порядок, поэтому совпадения нет:
SELECT ']Maria' REGEXP '[a]]'; +------------------------+ | ']Maria' REGEXP '[a]]' | +------------------------+ | 0 | +------------------------+
Символ - также может быть сопоставлен аналогичным образом:
SELECT '-Maria' REGEXP '[1-10]'; +--------------------------+ | '-Maria' REGEXP '[1-10]' | +--------------------------+ | 0 | +--------------------------+ SELECT '-Maria' REGEXP '[-1-10]'; +---------------------------+ | '-Maria' REGEXP '[-1-10]' | +---------------------------+ | 1 | +---------------------------+
Границы слов
Шаблоны :<: и :>: соответствуют началу и концу слова соответственно. Например:
SELECT 'How do I upgrade MariaDB?' REGEXP '[[:<:]]MariaDB[[:>:]]'; +------------------------------------------------------------+ | 'How do I upgrade MariaDB?' REGEXP '[[:<:]]MariaDB[[:>:]]' | +------------------------------------------------------------+ | 1 | +------------------------------------------------------------+ SELECT 'How do I upgrade MariaDB?' REGEXP '[[:<:]]Maria[[:>:]]'; +----------------------------------------------------------+ | 'How do I upgrade MariaDB?' REGEXP '[[:<:]]Maria[[:>:]]' | +----------------------------------------------------------+ | 0 | +----------------------------------------------------------+
Классы символов
Существует ряд сокращений для сопоставления определенных предопределённых классов символов. Они сопоставляются с шаблоном [:character_class:] (внутри набора []). Существуют следующие классы символов:
| Класс символов | Описание |
|---|---|
| alnum | Буквенно-цифровой |
| alpha | Буквенный |
| blank | Пробел |
| cntrl | Символы управления |
| digit | Цифры |
| graph | Печатные символы |
| lower | Буквенные символы в нижнем регистре |
| Печатные символы или пробел | |
| punct | Знаки препинания |
| space | Пробел, табуляция, перевод строки и возврат каретки |
| upper | Буквенные символы в верхнем регистре |
| xdigit | Шестнадцатеричная цифра |
Например:
SELECT 'Maria' REGEXP 'Mar[[:alnum:]]*'; +--------------------------------+ | 'Maria' REGEXP 'Mar[:alnum:]*' | +--------------------------------+ | 1 | +--------------------------------+
Помните, что по умолчанию сопоставления нечувствительны к регистру, если не используется бинарная строка, поэтому следующий пример, специально ищущий символ в верхнем регистре, интуитивно соответствует символу в нижнем регистре:
SELECT 'Mari' REGEXP 'Mar[[:upper:]]+'; +---------------------------------+ | 'Mari' REGEXP 'Mar[[:upper:]]+' | +---------------------------------+ | 1 | +---------------------------------+ SELECT BINARY 'Mari' REGEXP 'Mar[[:upper:]]+'; +----------------------------------------+ | BINARY 'Mari' REGEXP 'Mar[[:upper:]]+' | +----------------------------------------+ | 0 | +----------------------------------------+
Имена символов
Также существует ряд сокращений для сопоставления определённых предопределённых имён символов. Они сопоставляются с шаблоном [.character.] (внутри набора []). Существуют следующие классы символов:
| Имя | Символ |
|---|---|
| NUL | 0 |
| SOH | 001 |
| STX | 002 |
| ETX | 003 |
| EOT | 004 |
| ENQ | 005 |
| ACK | 006 |
| BEL | 007 |
| alert | 007 |
| BS | 010 |
| backspace | '\b' |
| HT | 011 |
| tab | '\t' |
| LF | 012 |
| newline | '\n' |
| VT | 013 |
| vertical-tab | '\v' |
| FF | 014 |
| form-feed | '\f' |
| CR | 015 |
| carriage-return | '\r' |
| SO | 016 |
| SI | 017 |
| DLE | 020 |
| DC1 | 021 |
| DC2 | 022 |
| DC3 | 023 |
| DC4 | 024 |
| NAK | 025 |
| SYN | 026 |
| ETB | 027 |
| CAN | 030 |
| EM | 031 |
| SUB | 032 |
| ESC | 033 |
| IS4 | 034 |
| FS | 034 |
| IS3 | 035 |
| GS | 035 |
| IS2 | 036 |
| RS | 036 |
| IS1 | 037 |
| US | 037 |
| space | ' ' |
| exclamation-mark | '!' |
| quotation-mark | '"' |
| number-sign | '#' |
| dollar-sign | '$' |
| percent-sign | '%' |
| ampersand | '&' |
| apostrophe | '\'' |
| left-parenthesis | '(' |
| right-parenthesis | ')' |
| asterisk | '*' |
| plus-sign | '+' |
| comma | ',' |
| hyphen | '-' |
| hyphen-minus | '-' |
| period | '.' |
| full-stop | '.' |
| slash | '/' |
| solidus | '/' |
| zero | '0' |
| one | '1' |
| two | '2' |
| three | '3' |
| four | '4' |
| five | '5' |
| six | '6' |
| seven | '7' |
| eight | '8' |
| nine | '9' |
| colon | ':' |
| semicolon | ';' |
| less-than-sign | '<' |
| equals-sign | '=' |
| greater-than-sign | '>' |
| question-mark | '?' |
| commercial-at | '@' |
| left-square-bracket | '[' |
| backslash | ' ' |
| reverse-solidus | ' ' |
| right-square-bracket | ']' |
| circumflex | '^' |
| circumflex-accent | '^' |
| underscore | '_' |
| low-line | '_' |
| grave-accent | '`' |
| left-brace | '{' |
| left-curly-bracket | '{' |
| vertical-line | '|' |
| right-brace | '}' |
| right-curly-bracket | '}' |
| tilde | '' |
| DEL | 177 |
Например:
SELECT '|' REGEXP '[[.vertical-line.]]'; +----------------------------------+ | '|' REGEXP '[[.vertical-line.]]' | +----------------------------------+ | 1 | +----------------------------------+
Объединение
Настоящая мощь регулярных выражений раскрывается, когда все вышеперечисленное объединяется, чтобы сформировать более сложные примеры. Репутация регулярных выражений в сложности обусловлена, казалось бы, сложной комбинацией нескольких регулярных выражений, когда на самом деле это просто вопрос понимания символов и того, как они применяются:
Первый пример не соответствует, так как, хотя Ma соответствует, i или r соответствуют только один раз до символов ia в конце.
SELECT 'Maria' REGEXP 'Ma[ir]{2}ia';
+------------------------------+
| 'Maria' REGEXP 'Ma[ir]{2}ia' |
+------------------------------+
| 0 |
+------------------------------+
Этот пример соответствует, так как i или r точно соответствуют дважды после Ma, в данном случае один r и один i.
SELECT 'Maria' REGEXP 'Ma[ir]{2}';
+----------------------------+
| 'Maria' REGEXP 'Ma[ir]{2}' |
+----------------------------+
| 1 |
+----------------------------+
Экранирование
С таким большим количеством специальных символов необходимо проявлять осторожность, чтобы правильно экранировать символы. Для правильного экранирования символа требуются два символа обратного слэша, (один для парсера MariaDB, один для библиотеки регулярных выражений). Например:
Для соответствия литеральному (Ma:
SELECT '(Maria)' REGEXP '(Ma'; ERROR 1139 (42000): Got error 'parentheses not balanced' from regexp SELECT '(Maria)' REGEXP '\(Ma'; ERROR 1139 (42000): Got error 'parentheses not balanced' from regexp SELECT '(Maria)' REGEXP '\\(Ma'; +--------------------------+ | '(Maria)' REGEXP '\\(Ma' | +--------------------------+ | 1 | +--------------------------+
Для соответствия r+: первые два примера неверны, так как они соответствуют r один или более раз, а не r+:
SELECT 'Mar+ia' REGEXP 'r+'; +----------------------+ | 'Mar+ia' REGEXP 'r+' | +----------------------+ | 1 | +----------------------+ SELECT 'Maria' REGEXP 'r+'; +---------------------+ | 'Maria' REGEXP 'r+' | +---------------------+ | 1 | +---------------------+ SELECT 'Maria' REGEXP 'r\\+'; +-----------------------+ | 'Maria' REGEXP 'r\\+' | +-----------------------+ | 0 | +-----------------------+ SELECT 'Maria' REGEXP 'r+'; +---------------------+ | 'Maria' REGEXP 'r+' | +---------------------+ | 1 | +---------------------+
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/regular-expressions-overview/