Проверка вхождения подстроки по шаблону

Функция

Поиск в строке подстроки по шаблону регулярного выражения.

Спецификация
 
< синтаксис >::=
< сопоставление >::=
'c' | 'i'
Общие правила
  1. < Символьное выражение > в < строке > может иметь следующие типы данных: CHAR, VARCHAR, NCHAR, NCHAR VARYING.

  2. < Символьный литерал > в < шаблоне > должен быть регулярным выражением.

  3. < Сопоставление > – модификатор, изменяющий стандартный механизм сопоставления символьных данных:

    • 'c' – сопоставление, чувствительное к регистру символов (по умолчанию);

    • 'i' – сопоставление, нечувствительное к регистру символов;

  4. В состав < шаблона > могут входить метасимволы привязки, квантификаторы и операторы повтора, предопределенные символьные классы, группы выражений, метасимволы ссылок (таблица 5).

Таблица 5. Элементы регулярного выражения < шаблона >
Метасимволы привязки
МетасимволОписание
^

Привязать выражение к началу строки:

select regexp_like('Привет, как дела?', '^Привет');
[true|
select regexp_like('Как дела?  привет', '^Привет');
[false|
$

Привязать выражение к концу строки:

select regexp_like('Привет, как дела?', 'Привет$');
[false|
select regexp_like('Как дела?  привет', 'привет$');
[true|

Примечание

Привязка строки в функции REGEXP_LIKE несколько отличается от предиката сопоставления LIKE: предиката выражения 'ab' эквивалентно выражению '%ab%', выражение '^ab$' эквивалентно 'ab'.

Квантификаторы и операторы повтора
КвантификаторОписание
*

Встречается 0 и более раз

select REGEXP_LIKE('test111', '1111*');
[false|
select REGEXP_LIKE('11123345', '1111*');
[true|
?

Встречается 0 или 1 раз

select REGEXP_LIKE('test1', '1111?');
[false|
select REGEXP_LIKE('11123345', '1111?');
[true|
+

Встречается 1 и более раз

select REGEXP_LIKE('test1', '5+');
[false|
select REGEXP_LIKE('11123345', '5+');
[true|
{m}

Встречается ровно m раз

select REGEXP_LIKE('test1', '3{2}');
[false|
select REGEXP_LIKE('11123345', '3{2}');
[true|
{m,}

Встречается по крайней мере m раз

select REGEXP_LIKE('test1', '3{2,}');
[false|
select REGEXP_LIKE('11123345','3{2,}');
[true|
{m, n}

Встречается по крайней мере m раз, но не более n раз

select REGEXP_LIKE('test1', '3{2,1}');
[false|
select REGEXP_LIKE('11123345','3{2,2}');
[true|
Предопределенные символьные классы
КлассОписание
[:alpha:]Буквы
[:lower:]Буквы в нижнем регистре
[:upper:]Буквы в верхнем регистре
[:digit:]Цифры
[:alnum:]Буквы и цифры
[:space:]Пробелы
Альтернативное сопоставление и группировка выражений
МетасимволОписание
|Альтернатива. Разделяет альтернативные варианты, часто используется с оператором группировки ()
( )Группа. Группирует подвыражения для альтернативы, квантификатора или ссылочности
[char]Список символов. Большинство метасимволов в списке символов представляют собой литеры, за исключением символьных классов и метасимволов ^ и -
[^char]Список символов, которые не должны присутствовать в строке
Метасимвол ссылки
МетасимволОписание
\digit

Обратная косая черта, за ней следует цифра от 1 до 9. Обратная косая черта связана с предыдущим сопоставлением с соответствующим номером заключенного в скобки подвыражения.

Обратная косая черта может иметь другое значение в регулярном выражении; в зависимости от контекста она может означать также символ Escape или обратную ссылку: '\n' – ссылка на результат выражения в скобках.

Например, обратная ссылка '\n': (abc|def)xy\1 соответствует строкам abcxyabc и defxydef, но не соответствует ни строке abcxydef, ни строке abcxy.

Обратная ссылка позволяет осуществлять поиск строки, не зная заранее фактической строки. Например, выражение ^(.*)\1$ соответствует строке, состоящей из двух идущих подряд одинаковых строк

Метасимволы стандарта языка Perl
МетасимволОписание
\d

Означает любую цифру. Эквивалент [0-9]. Например, выражение для проверки ввода телефонного номера

^\(\d{3}\) \d{3}-\d{4}$

С помощью этого шаблона ищется строка, которая начинается с трехзначного числа в скобках (поэтому используем перед символом скобка знак переключения \, чтобы интерпретировать ( или ) как скобку, а не как метасимвол группы), потом пробел, за которым следует ещё раз трехзначное число, дефис и в заключении четырехзначное число.

Номер (123) 456-3456 будет найден, а номер (234) 3456-3234 будет отвергнут

\DОзначает любой символ, кроме цифр. Эквивалент [^0-9]. Например, \d\D может означать 2b или 2$, но не 22
\w

Означает любой алфавитно-цифровой символ, включая символ подчеркивания '_'. Эквивалент [a-zA-Z0-9_].

Например, проверка допустимого адреса электронной почты \w+@\w+(\.\w+)+ С помощью этого шаблона ищется любой алфавитно-цифровой символ повторяющийся один или более раз (т.е. просто слово), затем символ @, затем снова слово, а после этого ищется строка по шаблону, состоящему из символа (поэтому используем знак переключения \) и слова, и этот шаблон может повторятся один или несколько раз.

Электронный адрес eldar52@mail.ru или eldar52@mail.org.ru будет найден, а eldar52@mail. будет отвергнут.

Если известно, что допустимый адрес имеет следующий вид name@mail.domain.something, тогда изменим регулярное выражение на поиск шаблона точно 2 раза

\w+@\w+(\.\w+){2}[$]

{2} означает, что шаблон (\.\w+) должен встречаться именно 2 раза, а за ним должно следовать либо конец строки, либо пробел

\WНаоборот (от \w); эквивалент [^a-zA-Z0-9_]
\sСоответствует любому символу whitespace (пробелу, табуляции и пустой строке); эквивалент [ \t\n\r\f\v]
\SСоответствует любому не-whitespace символу; эквивалент [^ \t\n\r\f\v]

Возвращаемое значение

Значение типа BOOLEAN: подстрока найдена (true) или не найдена (false).

Примеры
  1. select regexp_like('axb', 'a.b'), regexp_like('xaybx', 'a.b'), regexp_like('abba', 'a.b');
    |T|T|T|:
    
    select regexp_like('aab', '^a.b$'), regexp_like('abb', '^a.b$'), regexp_like('abb', '^a.b$');
    |T|T|T|:
    
    select regexp_like('axxb', 'a.b'), regexp_like('xaybx', '^a.b$'), regexp_like('abby', '^a.b$');
    |F|F|F|:
    
    
    select regexp_like('thing of beauty', '^thing'), regexp_like('small thing', '^thing'), regexp_like('thing of beauty', 'thing$'), regexp_like('small thing', 'thing$');
    |T|F|F|T|:
    
    select regexp_like('ba', 'b(an)*a'), regexp_like('bana', 'b(an)*a'), regexp_like('banana', 'b(an)*a'), regexp_like('yourbananasplit', 'b(an)*a');
    |T|T|T|T|:
    
    select regexp_like('abcef', '^ab[cd]ef$'), regexp_like('abdef', '^ab[cd]ef$');
    |T|T|:а
    
    select regexp_like('ab123','[^[:digit:]]'), regexp_like('123xy','[^[:digit:]]'), regexp_like('007ab','[^[:digit:]]'), regexp_like('abcxy','[^[:digit:]]'), regexp_like('12345','[^[:digit:]]');
    |T|T|T|T|F|:
    
    select regexp_like('Anderson', 'Anders(o|e|a)n'), regexp_like('Andersen', 'Anders(o|e|a)n'), regexp_like('Andersan', 'Anders(o|e|a)n');
    |T|T|T|:
    
    select regexp_like('Don', 'n$'), regexp_like('Ron', 'n$'), regexp_like('Stivenson', 'n$'), regexp_like('Bone', 'n$');
    |T|T|T|F|:
    
    select regexp_like('Alex', '^A'), regexp_like('Petrov Alex', '^A');
    |T|F|:
    
    select regexp_like('eldar52@mail.ru', '\w+@\w+(\.\w+)+'), regexp_like('eldar52@mail.org.ru', '\w+@\w+(\.\w+)+'), regexp_like('eldar52@mail.', '\w+@\w+(\.\w+)+');
    |T|T|F|:
    
    select regexp_like('name@mail.domain.something', '\w+@\w+(\.\w+){2}$'), regexp_like('name@mail.domain.something.something2', '\w+@\w+(\.\w+){2}$'), regexp_like('name@mail.domain.something.something2', '\w+@\w+(\.\w+){3}$'), regexp_like('name@mail.domain.something', '\w+@\w+(\.\w+){2}[$ ]');
    |T|F|T|T|:
  2. CREATE OR REPLACE TABLE contacts(l_name VARCHAR(30), p_number VARCHAR(30));
    insert into contacts values ('michael','(345) 345-4567');
    insert into contacts values ('michael2','345 345-4567');
    select * from contacts where not REGEXP_LIKE(p_number, '^\(\d{3}\) \d{3}-\d{4}$');
    
    select regexp_like('$$$SYSRL', '[\$\[\]\^\-]{3}'), regexp_like('ABC[$]DEF', '[\$\[\]\^\-]{3}'), regexp_like('FOO]$$D', '[\$\[\]\^\-]{3}'), regexp_like('FOO-^-D', '[\$\[\]\^\-]{3}'), regexp_like('[$$]', '^[\$\[\]\^\-]{3}$');
    |T|T|T|T|F|:
    
    select regexp_like('abefff', 'aB(cD)*eF+', 'i'), regexp_like('ABCDEF', 'aB(cD)*eF+', 'i'), regexp_like('ABCDE', 'aB(cD)*eF+', 'i');
    |T|T|F|:
              
  3. create or replace table regtest(name varchar(30), birthdate varchar(10), city varchar(20));
    insert into regtest values('Иванов','01011982','Воронеж');
    insert into regtest values('Зайцев','01111998','Киев');
    insert into regtest values('Петров','01011988','Москва');
    
    -- выборка из таблицы записей, которые содержат дату рождения в заданном формате
     REGEXP [0-9]{8}
    
    select * from regtest where regexp_like(birthdate,'[0-9]{8}');
    -- результат:
    --Зайцев,01111998,Киев
    --Иванов,01011982,Воронеж
    --Петров,01011988,Москва
    
    -- добавление записи с нестандартным форматом даты
    insert into regtest values('Волков','010A1988','Дмитров');
    select * from regtest where regexp_like(birthdate,'[0-9]{8}');
    --результат
    --Зайцев,01111998,Киев
    --Иванов,01011982,Воронеж
    --Петров,01011988,Москва
    
    select regexp_like('_', '^\w$');
    |T|:
    
    select regexp_like('2b', '\d\D'), regexp_like('2$', '\d\D'), regexp_like('22',
     '\d\D');
    |T|T|F|:
    
    select regexp_like('bce','(a|b)c(d|e)');
    |T|:
    
    select regexp_like('xayfa','x(a|b(c|d))y(e|f)\1'), regexp_like('xayff','x(a|b(c|d))y(e|f)\2'), regexp_like('xayfe','x(a|b(c|d))y(e|f)\2');
    |T|T|F|:
    
    select regexp_like('abcxyabc','(abc|def)xy\1'), regexp_like('defxydef','(abc|def)xy\1'), regexp_like('abcxydef','(abc|def)xy\1'), regexp_like('abcxy','(abc|def)xy\1');
    |T|T|F|F|:
    
    select regexp_like('forfor','(.*)\1'), regexp_like('forfot','(.*)\1');
    |T|F|:
              
  4. create or replace table tab25574_phone_2 (id int, fio char(40), mobile_phone char(15));
    insert into tab25574_phone_2 values (101, 'Hhh F.G.', '+7-900-900-9090');
    insert into tab25574_phone_2 values (102, 'Aaa B.C.', '8-700-700-7070');
    insert into tab25574_phone_2 values (102, 'Xx Y.Y.', '8-500-500-5050');
    
    !Выбираются по 3 записи для нижеследующих 6 запросов
    select * from tab25574_phone_2 where REGEXP_LIKE(fio, '[A-Z]{1}[a-z]{1,} ([A-Z]\.){2}');
    select * from tab25574_phone_2 where REGEXP_LIKE(fio, '([A-Z]\.){2}');
    select * from tab25574_phone_2 where REGEXP_LIKE(fio, '[A-Z]{1}[a-z]{1,}');
    select * from tab25574_phone_2 where REGEXP_LIKE(fio, '([A-Z]){1}([a-z]){1,}');
    select * from tab25574_phone_2 where REGEXP_LIKE(fio, '([[:upper:]]){1}([[:lower:]]){1,} ([[:upper:]]\.){2}');
    select * from tab25574_phone_2 where REGEXP_LIKE(fio, '[[:upper:]]{1}([[:lower:]]){1,} ([[:upper:]]\.){2}');