Oracle 正则表达式替换多次出现的用逗号包围的字符串

Oracle regex replace multiple occurrences of a string surrounded by commas

我正在寻找一种方法来替换(删除/替换为'')Oracle SQL 数据库中列的逗号分隔值列表中的字符串。例如,假设我有以下数据:

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

我希望用空字符串 '' 严格地(即不包括 'OSL')替换所有出现的子字符串 'SL'。 理想的结果应该是这样的:

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

我尝试使用 regexp_replace 函数,但它只会消除所有其他事件,即

SELECT 
    col1,
    regexp_replace(col1,'(^|,)(SL)($|,)','' || '' || '',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

我已经在其他具有单词边界 \b 构造可用的正则表达式实现中成功实现了我的目标,但尚未找到适用于 Oracle 正则表达式的解决方案。

更新

  1. 版本:我们使用的是 Oracle 版本 11g。
  2. 加例案例PI,SL,SLR,PK
  3. 其他示例案例 PK,SLSL,SLSLPK

因为 Oracle 的正则表达式在匹配后将匹配位置向前移动,不幸的是你需要做两次正则表达式

regexp_replace(regexp_replace(col1,'(^|,)(SL)(\W|$)','',1,0,'imn') ,'(^|,)(SL)(\W|$)','',1,0,'imn')

如果您可以选择字符串中未出现的特殊字符 - 我使用的是分号 (;),您可以按照以下步骤操作

1) 将每个逗号加倍为逗号 + 分号

2) 仅将分号作为可能的分隔符添加到模式中来执行正则表达式:

'(^|,|;)(SL)($|,|;) 

3) 删除所有分号

完整查询

SELECT 
    replace(regexp_replace(replace(col1,',',',;'),'(^|,|;)(SL)($|,|;)','',1,0,'imn'),';') as col2
FROM tab;

产生预期的结果

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