我的任务是将给定字符串中的相似数字/字符分组,
例如:
字符串4455599
的SQL的输出应为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
);
但是由于我当前正在使用
dense_rank
,因此查询失败并显示以下数据。445559944
,预期为44 555 99 44
,但为4444 555 99
。bb119911
,预期为bb 11 99 11
,但为1111 99 bb
。帮助我,欢迎所有正则表达式查询。
最佳答案
对救援的反向引用:
select
regexp_replace('4455599', '((.)\2*)', '\1 ')
from dual;
输出:
44 555 99
说明
((.)\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;
输出:
VAL RESULT
----------- ------------------
445559944 44 555 99 44
bb119911 bb 11 99 11
46455599464 4 6 4 555 99 4 6 4