oracle regex替换多个出现的由逗号包围的字符串

kmb7vmvb  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(625)

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

  1. select ('SL,PK') as col1 from dual
  2. union all
  3. select ('PK,SL') as col1 from dual
  4. union all
  5. select ('SL,SL') as col1 from dual
  6. union all
  7. select ('SL') as col1 from dual
  8. union all
  9. select ('PK') as col1 from dual
  10. union all
  11. select ('PI,SL,PK') as col1 from dual
  12. union all
  13. select ('PI,SL,SL,PK') as col1 from dual
  14. union all
  15. select ('PI,SL,SL,SL,PK') as col1 from dual
  16. union all
  17. select ('PI,SL,SL,SL,SL,PK') as col1 from dual
  18. union all
  19. select ('PI,OSL,SL,PK') as col1 from dual
  20. union all
  21. select ('PI,SL,SLR,PK') as col1 from dual
  22. COL1
  23. -----
  24. SL,PK
  25. PK,SL
  26. SL,SL
  27. SL
  28. PK
  29. PI,SL,PK
  30. PI,SL,SL,PK
  31. PI,SL,SL,SL,PK
  32. PI,SL,SL,SL,SL,PK
  33. PI,OSL,SL,PK
  34. PI,SL,SLR,PK

我希望用一个空字符串替换所有出现的子字符串'sl',严格来说(即不包括'osl'), '' . 理想结果如下:

  1. COL2
  2. -----
  3. ,PK
  4. PK,
  5. ,
  6. (null)
  7. PK
  8. PI,,PK
  9. PI,,,PK
  10. PI,,,,PK
  11. PI,,,,,PK
  12. PI,OSL,,PK
  13. PI,,SLR,PK

我试过使用 regexp_replace 功能,但它只会消除所有其他发生的情况,即。

  1. SELECT
  2. col1,
  3. regexp_replace(col1,'(^|,)(SL)($|,)','\1' || '' || '\3',1,0,'imn') as col2
  4. FROM (
  5. SELECT ('SL,PK') as col1 FROM dual
  6. UNION ALL
  7. SELECT ('PK,SL') as col1 FROM dual
  8. UNION ALL
  9. SELECT ('SL,SL') as col1 FROM dual
  10. UNION ALL
  11. SELECT ('SL') as col1 FROM dual
  12. UNION ALL
  13. SELECT ('PK') as col1 FROM dual
  14. UNION ALL
  15. SELECT ('PI,SL,PK') as col1 FROM dual
  16. UNION ALL
  17. SELECT ('PI,SL,SL,PK') as col1 FROM dual
  18. UNION ALL
  19. SELECT ('PI,SL,SL,SL,PK') as col1 FROM dual
  20. UNION ALL
  21. SELECT ('PI,SL,SL,SL,SL,PK') as col1 FROM dual
  22. UNION ALL
  23. SELECT ('PI,OSL,SL,PK') as col1 FROM dual
  24. UNION ALL
  25. SELECT ('PI,SL,SLR,PK') as col1 FROM dual
  26. )
  27. COL1 COL2
  28. ----- -----
  29. SL,PK ,PK
  30. PK,SL PK,
  31. SL,SL ,SL
  32. SL (null)
  33. PK PK
  34. PI,SL,PK PI,,PK
  35. PI,SL,SL,PK PI,,SL,PK
  36. PI,SL,SL,SL,PK PI,,SL,,PK
  37. PI,SL,SL,SL,SL,PK PI,,SL,,SL,PK
  38. PI,OSL,SL,PK PI,OSL,,PK
  39. PI,SL,SLR,PK PI,,SLR,PK

我已经在其他具有单词边界的regex实现中成功地实现了我的目标 \b 构造可用,但尚未找到针对oracle正则表达式的解决方案。
更新
版本:我们使用的是oracle版本11g。
附加示例案例 PI,SL,SLR,PK 其他示例案例 PK,SL , SL,SL , SL , PK

v64noz0r

v64noz0r1#

因为oracle的regex在匹配后将匹配位置向前移动,所以不幸的是,您需要执行两次regexp

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

nzrxty8p2#

如果你能选择一个不出现在字符串中的特殊字符-我用的是分号( ; )您可以按照以下步骤操作
1) 将每个逗号加倍为逗号+分号
2) 只执行regexp将分号作为可能的分隔符添加到模式中:

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

3) 删除所有分号
完整的查询

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

产生预期结果

  1. ,PK
  2. PK,
  3. ,
  4. (null)
  5. PK
  6. PI,,PK
  7. PI,,,PK
  8. PI,,,,PK
  9. PI,,,,,PK
  10. PI,OSL,,PK
  11. PI,,SLR,PK
展开查看全部

相关问题