Oracle - regexp_replace 以逗号分隔的字符串中包含空值

Oracle - regexp_replace with nulls in a comma separated Strings

我有一个场景,我必须根据位置替换逗号分隔字符串中的值。 以下是案例:

案例 1:

select regexp_replace('1,2,3','[^,]+',5,1,3)
from dual;

Returns 正确结果:1,2,5

案例二:

select regexp_replace('1,,3','[^,]+',5,1,3)
from dual;

Returns 结果:1,3

预期结果:1,5

使用正则表达式模式拆分字符串,正是因为它处理空标签的方式

所以我尝试了案例 3​​:

select regexp_replace('1,,3','(.*?)(,|$)',5,1,3)
from dual;

Returns 预期结果:1,5

但是如果我尝试这个案例 4:

select regexp_replace('1,2,3','(.*?)(,|$)',5,1,2)
    from dual;

Returns 结果:1,53

预期结果:1,5,3

我知道我在使用常规 expression.Is 时做错了 regexp_replace 在以上所有场景中工作?

我认为这会满足您的要求:

regexp_replace(col, '[^,]*(,|$)','5', 1, 3)

思路是捕获除逗号以外的0到N个连续字符,后接逗号或字符串结尾(后者被捕获)。然后将其替换为目标值,然后是捕获的部分。

如果你想坚持@Gary_W 的模式,那么你可以做一个(非常!)与@GMB 的提议类似的事情,但保留第二个捕获组:

 regexp_replace(str, '(.*?)(,|$)', '5', 1, 3)

一些示例数据:

with t (str) as (
            select '1,2,3' from dual
  union all select '1,,3' from dual
  union all select '1,2,3,4' from dual
  union all select '1,,3,4' from dual
  union all select '1,,,4,' from dual
  union all select ',,3' from dual
  union all select ',,3,' from dual
  union all select ',,,' from dual
  union all select '1' from dual
)
select str,
  regexp_replace(str, '(.*?)(,|$)', '5', 1, 3) as result
from t;

STR     RESULT    
------- ----------
1,2,3   1,2,5     
1,,3    1,,5      
1,2,3,4 1,2,5,4   
1,,3,4  1,,5,4    
1,,,4,  1,,5,4,   
,,3     ,,5       
,,3,    ,,5,      
,,,     ,,5,      
1       1         

@GMB 的方法对所有这些都得到了完全相同的结果,顺便说一下。

如果您想保留空的第三个元素,那么您可以使用 regexp_substr 版本来有选择地应用替换:

with t as (...)
select str,
  case when regexp_substr(str, '(.*?)(,|$)', 1, 3, null, 1) is not null
    then regexp_replace(str, '(.*?)(,|$)', '5', 1, 3)
    else str
  end as result
from t;

STR     RESULT    
------- ----------
1,2,3   1,2,5     
1,,3    1,,5      
1,2,3,4 1,2,5,4   
1,,3,4  1,,5,4    
1,,,4,  1,,,4,    
,,3     ,,5       
,,3,    ,,5,      
,,,     ,,,       
1       1