替换oracle中没有固定长度的子字符串

Posted

技术标签:

【中文标题】替换oracle中没有固定长度的子字符串【英文标题】:replace a substring in oracle which does not have fixed length 【发布时间】:2021-10-14 11:44:35 【问题描述】:

我的列值如下:

1.   input -- "This is ssn12345 string" 
2.   input -- "This is ssn 123456 string"
3.   input -- "This is ssn#12345 string"
4.   input -- "This is ssn#12345 string ssn1234678"
5.   input -- "This is ssn#12345 string ssn-123456"
6.   input -- "This is ssn#12345 string ssn 5678 9765"

这里ssn12345可以有动态长度(平均长度不固定)。

输出将是:

1.   output -- "This is ******** string"
2.   output -- "This is ********** string" 
3.   output -- "This is ********* string"
4.   output -- "This is ********* string *********"
5.   output -- "This is ********* string **********"
6.   output -- "This is ********* string *************"

我正在尝试替换从ssn 开始并以一些整数值结尾的字符串,例如我们以ssn1234ssn124567 开头。

我正在尝试以下查询,但它正在替换为单个 * 值。

select regexp_replace('This is ssn12345 string', 'ssn[^0-9.]+', '*') from dual
This is * string

我必须将 ssn 到下一个字符的值替换为这两个字符之间的 * 数。

谁能告诉我如何在 Oracle SQL 中实现这一点?如果需要更多详细信息,请告诉我。

【问题讨论】:

【参考方案1】:

只使用“非空白”:

select regexp_replace(
'This is ssn12345 string',
 'ssn\S+',
Rpad( '*', length(regexp_substr('This is ssn12345 string','ssn\S+') ), '*') 
) 
from dual 

【讨论】:

【参考方案2】:

你可以使用:

WITH data ( value, masked_value, end_pos ) AS (
  SELECT value,
         REGEXP_REPLACE(
           value,
           'ssn([ #]?\d+)+',
           RPAD(
             '*',
             LENGTH(
               REGEXP_SUBSTR(value, 'ssn([ #]?\d+)+', 1, 1)
             ),
             '*'
           ),
           1,
           1
         ),
         REGEXP_INSTR(
           value,
           'ssn([ #]?\d+)+',
           1,
           1,
           1
         )
  FROM   table_name
UNION ALL
  SELECT value,
         REGEXP_REPLACE(
           masked_value,
           'ssn([ #]?\d+)+',
           RPAD(
             '*',
             LENGTH(
               REGEXP_SUBSTR(masked_value, 'ssn([ #]?\d+)+', end_pos, 1)
             ),
             '*'
           ),
           end_pos,
           1
         ),
         REGEXP_INSTR(
           masked_value,
           'ssn([ #]?\d+)+',
           end_pos,
           1,
           1
         )
  FROM   data
  WHERE  end_pos > 0
)
SEARCH DEPTH FIRST BY value SET value_order
SELECT value, masked_value
FROM   data
WHERE  end_pos = 0;

其中,对于样本数据:

CREATE TABLE table_name ( value ) AS
SELECT 'This is ssn1 string' FROM DUAL UNION ALL
SELECT 'This is ssn12 string' FROM DUAL UNION ALL
SELECT 'This is ssn12345 string' FROM DUAL UNION ALL
SELECT 'This is ssn123456789 string' FROM DUAL UNION ALL
SELECT 'This is ssn#12345 string ssn 5678 9765' FROM DUAL;

输出:

VALUE MASKED_VALUE
This is ssn#12345 string ssn 5678 9765 This is ********* string *************
This is ssn1 string This is **** string
This is ssn12 string This is ***** string
This is ssn12345 string This is ******** string
This is ssn123456789 string This is ************ string

db小提琴here

【讨论】:

非常感谢

以上是关于替换oracle中没有固定长度的子字符串的主要内容,如果未能解决你的问题,请参考以下文章

PB中取字符串子串的函数是啥

2022华为机试真题 C++ 实现 字符串子序列II

华为OD机试真题Java实现判断字符串子序列真题+解题思路+代码(2022&2023)

C语言中如何用一个字符串替换一个主串中的子串

字符串子串去重之后的个数

sql server 里类似replace的字符串子串删除