Skip to content
Advertisement

Oracle regex replace multiple occurrences of a string surrounded by commas

I am looking for a way to replace (remove / replace with ”) a character string in a comma-separated list of values in a column in an Oracle SQL database. For example, suppose I have the following data:

select ('SL,PK') as col1 from dual
union all
select ('PK,SL') as col1 from dual
union all 
select ('SL,SL') as col1 from dual
union all 
select ('SL') as col1 from dual
union all 
select ('PK') as col1 from dual
union all 
select ('PI,SL,PK') as col1 from dual
union all 
select ('PI,SL,SL,PK') as col1 from dual
union all 
select ('PI,SL,SL,SL,PK') as col1 from dual
union all 
select ('PI,SL,SL,SL,SL,PK') as col1 from dual
union all 
select ('PI,OSL,SL,PK') as col1 from dual
union all 
select ('PI,SL,SLR,PK') as col1 from dual

COL1
-----
SL,PK
PK,SL
SL,SL
SL
PK
PI,SL,PK
PI,SL,SL,PK
PI,SL,SL,SL,PK
PI,SL,SL,SL,SL,PK
PI,OSL,SL,PK
PI,SL,SLR,PK

I am looking to replace all occurrences of the substring ‘SL’, strictly (i.e. not including ‘OSL’), with an empty string, ''. The ideal result would look like this:

COL2
-----
,PK
PK,
,
(null)
PK
PI,,PK
PI,,,PK
PI,,,,PK
PI,,,,,PK
PI,OSL,,PK
PI,,SLR,PK

I have tried to use the regexp_replace function, but it only eliminates every other occurence, i.e.

SELECT 
    col1,
    regexp_replace(col1,'(^|,)(SL)($|,)','1' || '' || '3',1,0,'imn') as col2
FROM (
    SELECT ('SL,PK') as col1 FROM dual
        UNION ALL 
    SELECT ('PK,SL') as col1 FROM dual
        UNION ALL 
    SELECT ('SL,SL') as col1 FROM dual
        UNION ALL
    SELECT ('SL') as col1 FROM dual
        UNION ALL
    SELECT ('PK') as col1 FROM dual
        UNION ALL
    SELECT ('PI,SL,PK') as col1 FROM dual
        UNION ALL 
    SELECT ('PI,SL,SL,PK') as col1 FROM dual
        UNION ALL 
    SELECT ('PI,SL,SL,SL,PK') as col1 FROM dual
        UNION ALL 
    SELECT ('PI,SL,SL,SL,SL,PK') as col1 FROM dual
        UNION ALL 
    SELECT ('PI,OSL,SL,PK') as col1 FROM dual
        UNION ALL 
    SELECT ('PI,SL,SLR,PK') as col1 FROM dual
)

COL1                COL2
-----               -----
SL,PK               ,PK
PK,SL               PK,
SL,SL               ,SL
SL                  (null)
PK                  PK
PI,SL,PK            PI,,PK
PI,SL,SL,PK         PI,,SL,PK
PI,SL,SL,SL,PK      PI,,SL,,PK
PI,SL,SL,SL,SL,PK   PI,,SL,,SL,PK
PI,OSL,SL,PK        PI,OSL,,PK
PI,SL,SLR,PK        PI,,SLR,PK

I have achieved my goal successfully in other regex implementations that have the word boundary b construct available, but have not found a solution for Oracle’s regex.

UPDATE

  1. Version: We are on Oracle version 11g.
  2. Addition example case PI,SL,SLR,PK
  3. Additional example cases PK,SL, SL,SL, SL, PK

Advertisement

Answer

because Oracle’s regex moves the matching position forward after a match you need to do regexp double times unfortunately

regexp_replace(regexp_replace(col1,'(^|,)(SL)(W|$)','13',1,0,'imn') ,'(^|,)(SL)(W|$)','13',1,0,'imn')
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement