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
- Version: We are on Oracle version 11g.
- Addition example case
PI,SL,SLR,PK
- 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')