oracle根据分隔符获取字符串

环境:11g


-- +表示对多个非,分组
select 
       regexp_substr('annn,bnn哈,cqwe,d哈哈', '[^][,]+', 1, 1) t1,
       regexp_substr('annn,bnn哈,cqwe,d哈哈', '[^][,]+', 1, 2) t2,
       regexp_substr('annn,bnn哈,cqwe,d哈哈', '[^][,]+', 1, 3) t3,
       regexp_substr('annn,bnn哈,cqwe,d哈哈', '[^][,]+', 1, 4) t4,  
       --等价
       regexp_substr('annn,bnn哈,cqwe,d哈哈', '[^,]+', 1, 1) e1,
       regexp_substr('annn,bnn哈,cqwe,d哈哈', '[^,]+', 1, 2) e2,
       regexp_substr('annn,bnn哈,cqwe,d哈哈', '[^,]+', 1, 3) e3,
       regexp_substr('annn,bnn哈,cqwe,d哈哈', '[^,]+', 1, 4) e4
  from dual;  
  
  如果你想直接输出为列:
  select REGEXP_SUBSTR('01#02#03#04', '[^#]+', 1, rownum) as newport 
  from dual connect by rownum <= regexp_count('01#02#03#04','#')+1;

  
--如果要取指定[]范围的数据怎么取?
select rtrim(regexp_substr('xxxx[aaa]yrwer[bb]tttt[ccc][dd]jjj', '[^[]+]',1,1),']'),
       regexp_substr('xxxx[aaa]yrwer[bb]tttt[ccc][dd]jjj', '[^[]+\)', 1, 2),
       regexp_substr('xxxx[aaa]yrwer[bb]tttt[ccc][dd]jjj', '[^[]+]', 1, 3),
       regexp_substr('xxxx[aaa]yrwer[bb]tttt[ccc][dd]jjj', '[^[]+]', 1, 4),
       regexp_count('xxxx[aaa]yrwer[bb]tttt[ccc][dd]jjj','\[')
from dual;


这里可以写成一个函数:
--三个入参,一个是左符号,一个右符号,一个拼接符
--出参,返回值指定符号拼接的字符串
create or replace function get_range_sign_str(p_left_sign varchar2,p_right_sign varchar2,p_text varchar2,p_str  varchar2 default ',')
return varchar2 is

v_temp varchar2(4000);
v_count pls_integer :=0;
begin
   if  p_left_sign is null or  p_right_sign is null or p_text is null then
      return null;
   end if;
   --获取分组次数
   select regexp_count(p_text,'\'||p_left_sign) into  v_count from dual;

   for x in 1.. v_count loop
      v_temp:=v_temp||  rtrim(regexp_substr(p_text, '[^'||p_left_sign||']+\'||p_right_sign,1,x),'\'||p_right_sign)||p_str;
   end loop;
   return rtrim(v_temp,p_str);
end;

--测试
select get_range_sign_str('(',')','xxxx(aaa)yrwer(bb)tttt(ccc)(dd)jjj') from dual;
select get_range_sign_str('[',']','xxxx[aaa]yrwer[bb]tttt[ccc][dd]jjj') from dual;



--如果你不想拼接,想直接返回一个table值的话
create or replace type v_tab_type is table of varchar2(4000);

create or replace function get_range_sign_table(p_left_sign varchar2,p_right_sign varchar2,p_text varchar2)
  return   v_tab_type pipelined
  is
  v_temp varchar2(4000);
  v_count pls_integer:=0;
  
begin
   if  p_left_sign is null or  p_right_sign is null or p_text is null then
      return ;
   end if;
   --获取分组次数
   select regexp_count(p_text,'\'||p_left_sign) into  v_count from dual;
   for x in 1.. v_count loop
      v_temp:= rtrim(regexp_substr(p_text, '[^'||p_left_sign||']+\'||p_right_sign,1,x),'\'||p_right_sign);
      --dbms_lock.sleep(1);
      pipe row(v_temp);
   end loop;
  return;
end;


--测试
select * from table(get_range_sign_table('(',')','xxxx(aaa)yrwer(bb)tttt(ccc)(dd)jjj')) ;
select * from table(get_range_sign_table('[',']','xxxx[aaa]yrwer[bb]tttt[ccc][dd]jjj')) ;

--如果编译报错: 必须声明标识符 'SYS.DBMS_LOCK'
--则需要授权
grant execute on dbms_lock to scott;

在这里插入图片描述

你可能感兴趣的:(数据库)