My task is to group similar digits/characters in a given string,
For e.g.:
The output of the SQL for the string 4455599 should be 44 555 99 and is working with following query:
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
);
But the query fails with the following data as I am currently using dense_rank.
445559944, expected 44 555 99 44 but getting 4444 555 99.
bb119911, expected bb 11 99 11 but getting 1111 99 bb.
Help me on this, welcome all regular expression query.
Backreferences to the rescue:
select
regexp_replace('4455599', '((.)\2*)', '\1 ')
from dual;
Output:
44 555 99
Explanation
((.)\2*) defines two capturing groups where:
(.) matches any single character and captures it in group 2.
\2* is a backreference to the character captured in group 2, which matches the same character zero or more times.
((.)\2*) therefore matches a sequence of one-or-more of the same character and captures the sequence in group 1.
\1 replaces the characters matched with the contents of group 1, followed by a space.
Backreferences are counted from left-to-right starting with 1 (group 0 is the entire match). So if you have the pattern (((a)b)c)d the innermost (a) is group 3, ((a)b) is group 2, (((a)b)c) is group 1, and if you're using a normal regex engine (not oracle's), the entire pattern (((a)b)c)d is captured in group 0.
Test cases
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;
Output:
VAL RESULT
----------- ------------------
445559944 44 555 99 44
bb119911 bb 11 99 11
46455599464 4 6 4 555 99 4 6 4
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With