Регулярные выражения произошли из теорий автоматов и формальных языков, поэтому поначалу производят устрашающее впечатление. Однако, их базовые понятия являются простыми и в то же время мощными.
Начиная с версии Oracle 10g регулярные выражения можно использовать напрямую в SQL запросах.
Шаблон регулярных выражений выражается в виде строки, содержащей следующие конструкции:
- Литеральные символы. Фактические символы, которые следует искать (Например, шаблон xyz соответствует только вхождению «xyz»)
- Метасимволы. Операции, определяющие алгоритмы, которые должны применяться во время поиска (Например, шаблон ^xyz соответсвует только строке, начинающейся с «xyz» — другие вхождения не учитываются)
Оператор REGEXP_LIKE
REGEXP_LIKE(исходная_строка, шаблон[, параметр_сопоставления])
исходная_строка | поддерживает символьные типы данных (CHAR, VARCHAR2, CLOB, NCHAR, NVARCHAR2 и NCLOB, но не LONG) |
шаблон | это другое название регулярного выражения |
параметр_сопоставления | позволяет использовать дополнительные параметры, такие как символ перехода на новую строку, многострочное форматирование и обеспечение управления учетом регистра |
Используется подобно оператору like в части where или же при определении ограничения на таблицу (constraint) .
Пример использования регулярных выражений:
Функция REGEXP_INSTR
REGEXP_INSTR(исходная_строка, шаблон[, начальная_позиция [, вхождение [, опция_возврата [, параметр_сопоставления ] ] ] ] )
исходная_строка | поддерживает символьные типы данных (CHAR, VARCHAR2, CLOB, NCHAR, NVARCHAR2 и NCLOB, но не LONG) |
шаблон | регулярное выражение |
начальная_позиция | позиция, с которой должен начинаться поиск |
вхождение | по умолчанию имеет значение 1, если пользователь не укажет поиск последовательных вхождений |
опция_возврата | значение по умолчанию 0, тогда возвратится начальная позиция шаблона; при значении 1 возвращается позиция символа, следующего за шаблоном |
параметр_сопоставления | позволяет использовать дополнительные параметры, такие как символ перехода на новую строку, многострочное форматирование и обеспечение управления учетом регистра |
Функция возвращает позицию символа, находящегосяв начале или конце соответствия для шаблона, так же как и ее аналог instr.
В отличие от instr, функция regexp_instr работает с начала строки и двигается вперед в поисках шаблона. Она не может начать с конца строки и перемещаться в обратном направлении.
Функция REGEXP_SUBSTR
REGEXP_SUBSTR(исходная_строка, шаблон[, позиция [, вхождение [,параметр_сопоставления]]])
исходная_строка | поддерживает символьные типы данных (CHAR, VARCHAR2, CLOB, NCHAR, NVARCHAR2 и NCLOB, но не LONG) |
шаблон | регулярное выражение |
позиция | позиция, с которой необходимо начинать поиск |
вхождение | по умолчанию имеет значение 1 |
параметр_сопоставления | позволяет использовать дополнительные параметры, такие как символ перехода на новую строку, многострочное форматирование и обеспечение управления учетом регистра |
Функция REGEXP_SUBSTR возвращает подстроку, которая соответствует шаблону.
Пример использования регулярных выражений:
- Извлечь подстроки используя разделители
- Разбить строку на строчки по 100 символов, не разбивая слова
- Разбор строки на числа с разделителем дробной части в виде точки
Функция REGEXP_REPLACE
REGEXP_REPLACE(исходная_строка, шаблон [, строка_замены [, позиция[,вхождение, [параметр_сопоставления]]]])
исходная_строка | поддерживает символьные типы данных (CHAR, VARCHAR2, CLOB, NCHAR, NVARCHAR2 и NCLOB, но не LONG) |
шаблон | регулярное выражение |
шаблон замены | текст для замены каждого вхождения |
позиция | позиция, с которой необходимо начинать поиск |
вхождение | по умолчанию имеет значение 1 |
параметр_сопоставления | позволяет использовать дополнительные параметры, такие как символ перехода на новую строку, многострочное форматирование и обеспечение управления учетом регистра |
REGEXP_REPLACE возвращает измененную входную строку, в которой все вхождения шаблона заменены значением, переданным в параметре строка_замены.
Пример использования регулярных выражений:
- Замена кратных пробелов на один
- Заменить подстроку, но только если перед ней пробел или запятая
- Оставить только цифры или символы
Регулярные выражения Oracle
Таблица 1: Метасимволы привязки
Метасимвол | Описание | Пример |
^ | Привязать выражение к началу строки | «^привет» соответствует «привет, как дела», но не «как дела, привет» |
$ | Привязать выражение к концу строки | «привет$» соответсвует «как дела, привет», но не «привет, как дела» |
Таблица 2: Квантификаторы и операторы повтора
Квантификатор | Описание | Пример |
* | Встречается 0 и более раз | REGEXP_REPLACE(str, ’11*’, ‘1’) Результат: test11 => test1 11123345 => 123345 |
? | Встречается 0 или 1 раз | |
+ | Встречается 1 и более раз | REGEXP_LIKE(str,’5+’) Результат: test11 => false 11123345 => true |
{m} | Встречается ровно m раз | REGEXP_LIKE(str,’3{2}’) Результат: test11 => false 11123345 => true |
{m,} | Встречается по крайней мере m раз | |
{m, n} | Встречается по крайней мере m раз, но не более n раз |
Таблица 3: Предопределенные символьные классы POSIX
Класс символов | Описание |
. | Любой символ |
[:alpha:] | Буквы |
[:lower:] | Буквы в нижнем регистре |
[:upper:] | Буквы в верхнем регистре |
[:digit:] | Цифры |
[:alnum:] | Буквы и цифры |
[:space:] | Пробелы (не печатаемые символы), такие как перевод каретки, новая строка, вертикальная табуляция и подача страницы |
[:punct:] | Знаки препинания |
[:cntrl:] | Управляющие символы (не печатаемые) |
[:print:] | Печатаемые символы |
Таблица 4: Альтернативное сопоставление и группировка выражений
Метасимвол | Описание | |
| | Альтернатива | Разделяет альтернативные варианты, часто используется с оператором группировки () |
( ) | Группа | Группирует подвыражения для альтернативы, квантификатора или ссылочности |
[char] | Список символов | Обозначает список символов; большинство метасимволов в списке символов представляют собой литеры, за исключением символьных классов и метасимволов ^ и — |
[^char] | Список символов | Список символов, которые не должны присутствовать в строке |
Таблица 5: Метасимвол ссылки
Метасимвол | Описание | |
\digit | Обратная косая черта |
За ней следует цифра от 1 до 9, обратная косая черта связана с предыдущим сопоставлением с соответствующим номером заключенного в скобки подвыражения. (Заметьте: Обратная косая черта может иметь другое значение в регулярном выражении; в зависимости от контекста она может означать также символ Escape |
Более полную информацию можно прочитать здесь Using Regular Expressions in Oracle Database
Вывести три поля : наименование (naimen ), дату (GR0) , дату которая написали в наименование .
Использовать регулярные выражения . Таблица atfm.uch_vse.
@Али
А в чем вопрос заключается?
@rudev
Наверное он хочет чтобы ему помогли сформировать SQL запрос соответствующий..
Что то вроде:
???
Подскажите, как оптимально сделать запрос с паспортами российскими нового образца. Если серия иногда указывается с номером. Вывести и серию, и номер, заранее спасибо
Андрей, в подскажите, с запросом выше, если не затруднит
@Andrey
Народ, помогите пожалуйста !!
Нужно сделать вот такой запрос:
Выявить наименования содержащие лишние спец.символы (например, повторяющиеся пробелы, \, *, ^, ?, [, ], {, }, $, ., +, , (, ,))
Нужно сделать через regexp_like
Кто знает, как в Оракле 11 при помощи регулярного выражения разбить предложение на слова , чтобы при этом пустые слова тоже учитывались. Слово в данном случае это ноль или больше символов между двумя разделителями, в качестве которых также служат начало и конец предложения. Без учета пустых символов легко regexp_substr(str, ‘[^;]+’,1,n) — n-е слово. Если вместо + поставить * то тогда и разделитель каждый тоже является отдельным словом
select level, replace(regexp_substr(‘ff,rrr,,y’||’,’, ‘[^,]*,’,1,level),’,’) from dual
connect by regexp_substr(‘ff,rrr,,y’||’,’, ‘[^,]*,’,1,level) is not null
или так
select level, replace(regexp_substr(‘ff,rr;rrr,,y’, ‘[^,]*(,|$)’,1,level),’,’) from dual
connect by regexp_substr(‘ff,rr;rrr,,y’, ‘[^,]*(,|$)’,1,level) is not null
Да, если б еще оракл «lookahead/lookbehind» (?=)(?<=) поддерживал, чтоб не надо было префикс/постфикс из результата выковыривать отдельно…
Добрый день, уважаемые программисты!
Подскажите, пожалуйста, как реализовать фильтр на символы?
Допустимые значения в имени: [ 0-9 a-z A-Z — + (пробел) , _ . «], а лишние символы удалить или заменить.
Буду благодарна за ответ!
Нашла решение!
FUNCTION REGREX_STR(STR IN VARCHAR2) RETURN RETURN VARCHAR2 IS
RES VARCHAR(100);
BEGIN
select regexp_replace(tt.s, ‘[‘||tt.new_str||’^]’) into RES
from
( select str as s, trim(regexp_replace(t.str, ‘[[:alnum:][:space:]+-_.,»]’)) as new_str
from (
select STR as str from dual
) t
where regexp_like(t.str, ‘[[:alnum:][:space:]+-_.,»]’)
) tt
where regexp_like(tt.s, ‘[‘||tt.new_str||’^]’);
RETURN RES;
END;
Подскажите. как можно из строки убрать фамилию которая повторяется несколько раз?
Для примера: Иванов И.И., Иванов И.И., Петров Д.Д., Васечкин А.А.
Выводить как: Иванов И.И., Петров Д.Д., Васечкин А.А.
Результат:
UNIQ_NAME
—————
Петров Д.Д.
Васечкин А.А.
Иванов И.И.
imp, еще простой вариант для вывода одной строкой:
select REGEXP_REPLACE(‘Иванов И.И., Иванов И.И., Петров Д.Д., Васечкин А.А.’,'(([^,]+), ?)\1′,’\1′,1,1,’i’) as str
from dual
Результат:
STR
——
Иванов И.И., Петров Д.Д., Васечкин А.А.
Доброго времени суток.
Подскажите, как с помощью regexp_replace оставить из строки «АПКН@1112» только АП пробую
Результат: АП
но если строка «АКН@1112» возвращает А, мне необходимо, что бы АП воспринимал как группу пробовал ‘[^(АП)]’ не работает.
@Vladimir
А точно нужен именно regexp_replace ?
Если нужно, чтобы строка начиналась на АП, то проще искать через like ‘АП%’
Можно конечно еще через regexp_substr:
А если просто наличие АП, то :
Может кто подскажет, нужно чтобы выводились все значения расположенные после двоеточия, но при этом, если в теге двоеточия нет, то выводилось его значение. К примеру, для строки «ffgfg:45454|fdfd:511|00|mck:9» должно выводится 45454|511|00|9, а у меня получается 45454|511|9.
Написала вот что, все выводит почти верно, кроме тех значений, где после | не было двоеточия.. Т.е. в моем примере он Не выодит 00, а должен!
declare
p_element_path varchar2(4000);
p_element_path_new varchar2(4000);
cnt number := 0;
begin
p_element_path := ‘ffgfg:45454|fdfd:511|00|mck:9’;
for i in (SELECT REGEXP_SUBSTR(p_element_path, ‘[^|;]+’, REGEXP_INSTR(p_element_path, ‘[^:;]+’,1, LEVEL, 0), 1) a1
FROM DUAL
CONNECT BY REGEXP_INSTR(p_element_path, ‘[^:;]+’, 1, LEVEL) > 0) loop
cnt:= cnt+1;
if cnt >1 then
p_element_path_new:= p_element_path_new||’|’||i.a1;
end if;
end loop;
end;
@Nasty
Обработку пустого значения, можно сделать через nvl
@Nasty
Коллеги, а как быть, если нужно использовать управляющие символы, например, кавычку или скобку? Как например, найти слово, которое заключено в одинарные кавычки или в скобки?
Так не пойдет?
with t as (
select ‘(img src=»http://apps-oracle.ru/logo2.png» alt)=»»/>DDD’ str from dual
)
select regexp_substr(str, ‘\(.*\)’) as res, chr(37) ypr, ascii(‘(‘) psk, ascii(‘)’) lsk,
chr(40) s_40, chr(41) s_41
from t;
ПОМОГИТЕПОЖАЛУЙСТА!
Создать запрос для вывода фамилий служащих и их зарплат, обозначенных звездочками (каждая звездочка обозначает 100 долларов).
Добрый день! Подскажите пожалуйста, какой фильтр(выражение)правильно поставить чтобы в столбце можно было отфильтровать строки «начиная с»
@Аноним
where Столбец like ‘начиная с%’
@АНОН
length(поле со звездочками)*100
Добрый день!
Имеется следующая пример в Oracle, хотелось бы, что он заменил | на ; везде, кроме где есть предшествующий символ /
select regexp_replace(’16|2/|3 |7 |8′, ‘(?<!\/)\|', ';') from dual;
Регулярку проверил для питона, PHP она корректно работает, а для Oracle не понимаю, как сделать альтернативу.
Коллеги, подскажите как заменить вхождение «Акционерное общество» на «АО» без учета регистра?
В функции regexp_replace ставлю в конце параметр ‘i’, но он все равно не меняет. При этом если «Акционерное общество» заменить просто любым одним символом, то меняет
Есть проблема, нужно выдернуть все номера телефонов из поля адреса, все значения хранятся через запятую, в одном поле адреса, вместе с адресом, телефона может не быть, может быть 1, может быть 2. Никак не могу найти решение, пробовал через REGEXP_SUBSTR, вероятно в силу того, что только начал с ним разбираться получаю 1 первый номер и все, как можно сделать, написал так:
select
address,
REGEXP_SUBSTR(address,’\D{5}?\(?\d{3}\)?[[:space:]\.\-]?\d{3}[[:space:]\.\-]?\d{4}’,1,1) tel
from kadrobject
where kadrid=’2004′
Пример данных:
Москва, Генерала Белова, д. 100, кв. 120, дом. 75555555555, моб. 7 955 555-5555