How to use regexp_replace to replace mutiple occurance of substring?

hi,
would you know if i can use regexp_replace to replace multiple occurances of a substring with in a string, with a single occurance of the string?
i have a string like so..
'XP78380;XT42564;ZX03942;XP78380;XT42564;'
i want to remove duplicate occurance of 'XP78380' and 'XT42564' and have only one occurance.
i wrote a small pl/sql block, but want to check if this can be done with a single regexp_replace?
Rao_SAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
sdstuberConnect With a Mentor Commented:
Assuming the output should be sorted alphabetically

select listagg(str,';') within group (order by str) ||';' from
(SELECT     DISTINCT REGEXP_SUBSTR('XP78380;XT42564;ZX03942;XP78380;XT42564;', '[^;]+', 1, LEVEL) str
      FROM DUAL
CONNECT BY LEVEL <= REGEXP_COUNT('XP78380;XT42564;ZX03942;XP78380;XT42564;', '[^;]+'));


If they won't be sorted alphabetically but you need to preserve the initial order  then


SELECT LISTAGG(str, ';') WITHIN GROUP (ORDER BY lvl) || ';'
  FROM (SELECT str, lvl, ROW_NUMBER() OVER (PARTITION BY str ORDER BY lvl) rn
          FROM (SELECT     REGEXP_SUBSTR('XP78380;XT42564;ZX03942;XP78380;XT42564;', '[^;]+', 1, LEVEL)
                               str,
                           LEVEL lvl
                      FROM DUAL
                CONNECT BY LEVEL <=
                               REGEXP_COUNT('XP78380;XT42564;ZX03942;XP78380;XT42564;', '[^;]+')))
 WHERE rn = 1;
0
 
slightwv (䄆 Netminder)Connect With a Mentor Commented:
Main code copied from:
http://volder-notes.blogspot.com/2007/10/removing-duplicate-elements-from-string.html

Not sure how efficient it is over the good old str2tbl and listagg to put it all back together but you can test both and see.

Try this:
WITH t AS (SELECT 'XP78380;XT42564;ZX03942;XP78380;XT42564;' str FROM dual)
    --
select str, rtrim(str_new,',') new_str from t
model
dimension by (0 dim)
measures(str, str||',' str_new)
rules iterate(100) until (str_new[0] = previous(str_new[0]))
(str_new[0]=regexp_replace(str_new[0],'(^|;)([^;]+;)(.*?;)?\2+','\1\2\3'));

Open in new window

0
 
Rao_SAuthor Commented:
wow! thank you, i need to spend some time and understand how this works, my string is not a constant, at one time it can have 10 elements in it separated by a ';' at another time it might have just 2 elements in it, regardless of the number of elements in it, i need to parse it and remove dups...
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
sdstuberConnect With a Mentor Commented:
and another version,  no aggregation or sorting needed, simply find the dups and remove them


SELECT CASE
           WHEN INSTR(str, 'XT42564', 1, 2) > 0
           THEN
               REGEXP_REPLACE(str, 'XT42564' || ';', NULL, INSTR(str, 'XT42564', 1, 2), 0)
           ELSE
               str
       END
           str
  FROM (SELECT CASE
                   WHEN INSTR(str, 'XP78380', 1, 2) > 0
                   THEN
                       REGEXP_REPLACE(str, 'XP78380' || ';', NULL, INSTR(str, 'XP78380', 1, 2), 0)
                   ELSE
                       str
               END
                   str
          FROM (SELECT 'XP78380;XT42564;ZX03942;XP78380;XT42564;' str FROM DUAL))
0
 
Rao_SAuthor Commented:
wow!!!!!!
this is wonderful too! i knew regexp was very powerful, but just dint know how to use it!
thank you very much, i love the first select!! also i have never used a connect by level before..
0
 
Rao_SAuthor Commented:
wonderful solutions!
0
All Courses

From novice to tech pro — start learning today.