Для того чтобы разбить строку на подстроки, используя разделитель «;», можно воспользоваться следующим запросом.
Разделитель, конечно, может быть разный.
SQL> SELECT regexp_substr(str, '[^;]+', 1, level) str 2 FROM ( 3 SELECT ' 1; 2; test1.' str FROM dual ) t 4 CONNECT BY instr(str, ';', 1, level - 1) > 0 5 ; STR ------------- 1 2 test1.
Если хотим разбить на слова используя в виде разделителя пробел, то можно использовать perl синтаксис:
SQL> SELECT regexp_substr(str, '\S+', 1, level) str 2 FROM ( 3 SELECT ' 1 2 test1.' str FROM dual ) t 4 connect by regexp_substr(str,'\S+',1,level) is not null 5 ; STR ----------- 1 2 test1.
Другие примеры…
Если требуется разделить не только на строки, но и на столбцы:
SQL> column str1 format a10; SQL> column str2 format a10; SQL> column str3 format a10; SQL> select 2 regexp_substr(str, '[^=]+', 1, 1) as str1, 3 regexp_substr(str, '[^=]+', 1, 2) as str2, 4 regexp_substr(str, '[^=]+', 1, 3) as str3 5 from ( 6 select regexp_substr(str, '[^@]+', 1, level) str 7 from ( 8 select rtrim('field1=field2=field3@field3=field4@field5=field6=field7@','@') str 9 from dual) 10 CONNECT BY REGEXP_INSTR (str, '@', 1, level - 1) > 0 11 ); STR1 STR2 STR3 ---------- ---------- ---------- field1 field2 field3 field3 field4 field5 field6 field7
или
select regexp_substr(str, '[^\.]+', 1, 1 ) str1 ,regexp_substr(str, '[^\.]+', 1, 2 ) str2 ,regexp_substr(str, '[^\.]+', 1, 3 ) str3 ,regexp_substr(str, '[^\.]+', 1, 4 ) str4 ,regexp_substr(str, '[^\.]+', 1, 5 ) str5 ,regexp_substr(str, '[^\.]+', 1, 6 ) str6 ,regexp_substr(str, '[^\.]+', 1, 7 ) str7 ,regexp_substr(str, '[^\.]+', 1, 8 ) str8 ,regexp_substr(str, '[^\.]+', 1, 9 ) str9 ,regexp_substr(str, '[^\.]+', 1, 10) str10 ,regexp_substr(str, '[^\.]+', 1, 11) str11 ,regexp_substr(str, '[^\.]+', 1, 12) str12 from ( select '01000.7961400000.0.0.0.001.0.K0101.0.0.0.0' str from dual)
Пример разбора на лексемы для нескольких строк
SQL> with t as ( 2 select 'a;б;в' as str, 1 as id from dual 3 union all 4 select 'г;д;' as str, 2 from dual 5 union all 6 select null as str, 3 from dual 7 union all 8 select 'p' as str, 4 from dual 9 ) 10 select regexp_substr(str, '[^;]+', 1, level) str2 , t.* from t 11 CONNECT BY instr(trim(';' from str), ';', 1, level - 1) > 0 12 and prior id = id 13 and prior dbms_random.value is not null 14 ; STR2 STR ID ---------- ----- ---------- a a;б;в 1 б a;б;в 1 в a;б;в 1 г г;д; 2 д г;д; 2 3 p p 4 7 rows selected
Пример разбора формулы
SQL> with t as 2 ( 3 select 'a+b-v-s' str from dual 4 ) 5 select case when level != 1 then regexp_substr(str, '[*+|-]', 1, level-1) 6 end prefix_sign, 7 regexp_substr(str, '[^+|-]+', 1, level) str, 8 regexp_substr(str, '[*+|-]', 1, level) postfix_sign 9 from t 10 CONNECT BY regexp_substr(str, '[^+|-]+', 1, level) is not null; PREFIX_SIGN STR POSTFIX_SIGN ----------- ------- ------------ a + + b - - v - - s
Спасибо, очень помогло
Очень полезная информация, спасибо!
«Пример разбора на лексемы для нескольких строк» не работает, если между двумя раделителями пусто, например ‘г;д;’ разбивается на лексемы также, как и ‘г;;д’
«Пример разбора на лексемы для нескольких строк» не работает, если между двумя раделителями пусто, например ‘г;д;’ разбивается на лексемы также, как и ‘г;;д’
Чтобы гарантировать наличие символов между разделителями «;», можно после разделитемя с помощью replace вставить что-нибудь «ненужное» (пробел), а потом с помощью substr( … ,2 ) убрать это «ненужное»
with t as
(select ‘a;б;в’ as str, 1 as id from dual union all
select ‘г;д;’ as str, 2 from dual union all
select ‘г;;д’ as str, 3 from dual union all
select null as str, 4 from dual union all
select ‘p’ as str, 5 from dual )
select t.*,
regexp_substr(str, ‘[^;]+’, 1, level) str2,
substr(regexp_substr(replace(‘;’||str, ‘;’, ‘; ‘), ‘[^;]+’, 1, level),2) str3
from t
CONNECT BY instr(trim(‘;’ from str), ‘;’, 1, level — 1) > 0
and prior id = id
and prior dbms_random.value is not null;
Большое спасибо за полезную информацию!
Спасибо, очень полезная информация!
Не могу понять как применить это в моём случае.
Есть строка HR||166666|…
и есть строка HR|2777777|166666|…
Вопрос в том как составить шаблон для regexp_substr чтобы и в первом и во втором случае по одному шаблону и номеру вхождения, выбирало 3ю секцию — 166666.
Чтобы regexp_substr(str, /*шаблон*/ , 1, 3) давало и в первом и во втором случае 166666.
Заранее спасибо за ответ!