Oracle中的字符串顺序分组

ajm*_*d04 6 regex sql oracle oracle11g

我的任务是对给定字符串中的相似数字/字符进行分组,例如:字符串的SQL输出4455599应该是44 555 99并且正在使用以下查询:

with t(str)
as (
  select '4455599' from dual
)
select listagg(str_grouped ,' ') within group (order by rownum) str_split
from(
    select listagg ( str) within group ( order by lvl) str_grouped
    from(
        select level lvl, 
               substr(str,level,1) str, 
               dense_rank() over( order by substr(str,level,1)) drank_no
        from t
          connect by level <= length(str)
    )
 group by drank_no
  );
Run Code Online (Sandbox Code Playgroud)

但是查询失败了,因为我正在使用以下数据dense_rank.

445559944,期待44 555 99 44但得到4444 555 99.

bb119911,期待bb 11 99 11 但得到1111 99 bb.

帮助我,欢迎所有正则表达式查询.

bee*_*jay 9

对救援的反思:

select 
    regexp_replace('4455599', '((.)\2*)', '\1 ')
from dual;
Run Code Online (Sandbox Code Playgroud)

输出:

44 555 99 
Run Code Online (Sandbox Code Playgroud)

说明

((.)\2*) 定义两个捕获组,其中:

(.) 匹配任何单个字符并在第2组中捕获它.

\2* 是对第2组中捕获的角色的反向引用,它将相同的角色匹配零次或多次.

((.)\2*) 因此匹配一个或多个相同字符的序列并捕获组1中的序列.

\1 替换与组1的内容匹配的字符,后跟空格.

反向引用从左到右计数从1开始(组0是整个匹配).因此,如果您具有模式,(((a)b)c)d则最内层(a)是组3,((a)b)组2 (((a)b)c)是组1,如果您使用的是正常的正则表达式引擎(不是oracle的),则整个模式(((a)b)c)d将在组0中捕获.

测试用例

select 
    val, regexp_replace(val, '((.)\2*)', '\1 ') as result
from (
    select '445559944' as val from dual
    union all select 'bb119911' as val from dual
    union all select '46455599464' as val from dual
) foo;
Run Code Online (Sandbox Code Playgroud)

输出:

VAL         RESULT
----------- ------------------
445559944   44 555 99 44 
bb119911    bb 11 99 11 
46455599464 4 6 4 555 99 4 6 4 
Run Code Online (Sandbox Code Playgroud)