Oracle REGEXP_REPLACE 字符串替换 'n'从 nn 位置开始的时间

发布于 2025-01-10 20:24:52 字数 314 浏览 0 评论 0原文

我想替换“|”和 '_'。替换应该从第nn个字符开始并替换n次。例如,

ABC|1234|mno|p|q|r|456|XYZ|QRS|TUV ====> ABC|1234|mno|p_q_r|456|XYZ|QRS|TUV

在上面的示例中 nn=14 和 n=3

到目前为止,我已经尝试过,但没有得到预期的结果

SELECT REGEXP_REPLACE('ABC|1234|mno|p|q|r|456|XYZ', '[|]', '_',14) rep_str FROM DUAL

I want to replace '|' with '_'. The replacement should start from nnth character and replace n times. For e.g.

ABC|1234|mno|p|q|r|456|XYZ|QRS|TUV ====> ABC|1234|mno|p_q_r|456|XYZ|QRS|TUV

In above example nn=14 and n=3

So far, I've tried this but not getting the expected results

SELECT REGEXP_REPLACE('ABC|1234|mno|p|q|r|456|XYZ', '[|]', '_',14) rep_str FROM DUAL

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

红ご颜醉 2025-01-17 20:24:52

在您的简单示例中,指定两个事件更容易:

  regexp_replace(
      str
     , '\|([^|]+)'
     ||'\|([^|]+)' -- 2 times just to make it more readable
     ||'(.*)'      --  others
     ,'_\1_\2\3'
     ,14
  )

带有测试数据的完整示例: DBFiddle

with t as (
select
  'ABC|1234|mno|p|q|r|456|XYZ|QRS|TUV' str
 ,'ABC|1234|mno|p_q_r|456|XYZ|QRS|TUV' chk 
from dual
)
select
  str,chk,
  regexp_replace(
      str
     , '\|([^|]+)'
     ||'\|([^|]+)' -- 2 times just to make it more readable
     ||'(.*)'      --  others
     ,'_\1_\2\3'
     ,14
  ) as str2
from t
/

或者,如果您使其更加可定制并更容易指定替换数量,您可以使用简单的具有如下循环的内联 pl/sql 函数: DBFiddle

with function regexp_replaces(
    source_char  varchar2
   ,pattern      varchar2
   ,replace_char varchar2
   ,position     int
   ,cnt          int
  ) return varchar2
as
  res varchar2(4000):=source_char;
begin
  for i in 1..cnt loop
    res:=regexp_replace(res,pattern,replace_char,position,1);
  end loop;
  return res;
end;
select
  str,chk,
  regexp_replaces(str,'\|','_',14,2) as str2
from t;

In your simple example it's easier to specify both 2 occurences:

  regexp_replace(
      str
     , '\|([^|]+)'
     ||'\|([^|]+)' -- 2 times just to make it more readable
     ||'(.*)'      --  others
     ,'_\1_\2\3'
     ,14
  )

Full example with test data: DBFiddle

with t as (
select
  'ABC|1234|mno|p|q|r|456|XYZ|QRS|TUV' str
 ,'ABC|1234|mno|p_q_r|456|XYZ|QRS|TUV' chk 
from dual
)
select
  str,chk,
  regexp_replace(
      str
     , '\|([^|]+)'
     ||'\|([^|]+)' -- 2 times just to make it more readable
     ||'(.*)'      --  others
     ,'_\1_\2\3'
     ,14
  ) as str2
from t
/

Or if you make it more customizable and specify number of replacement easier, you can use simple inline pl/sql function with a loop like this: DBFiddle

with function regexp_replaces(
    source_char  varchar2
   ,pattern      varchar2
   ,replace_char varchar2
   ,position     int
   ,cnt          int
  ) return varchar2
as
  res varchar2(4000):=source_char;
begin
  for i in 1..cnt loop
    res:=regexp_replace(res,pattern,replace_char,position,1);
  end loop;
  return res;
end;
select
  str,chk,
  regexp_replaces(str,'\|','_',14,2) as str2
from t;
云雾 2025-01-17 20:24:52

您可以使用普通的 substr/instr 来完成此操作,但需要仔细处理边缘情况。提取您需要的零件并更换其中的所有管道。然后把所有东西放回去。

<前><代码>与
--
函数replace_n(
varchar2 中的 str,
start_ 号,
count_ 数量

返回varchar2
作为
开始
返回
/*起始部分不变*/
子字符串(字符串,1,开始_)
/*替换:定位第 n - 1 次出现的管道*/
||翻译(
substr(str, start_ + 1, instr(str, '|', start_, count_-1) - start_)
, '|'
, '_'

/*剩余字符串*/
|| substr(str, instr(str, '|', start_, count_ - 1) + 1)
;
结尾;
--
a(a) 作为 (
选择
'ABC|1234|mno|p|q|r|456|XYZ|QRS|TUV'
从双

选择replace_n(a, 14, 3)作为res
从一个

<前>|资源 |
| :--------------------------------- |
| ABC|1234|mno|p_q_r|456|XYZ|QRS|TUV |

db<>fiddle 此处

UPD :或者如果您要替换大小为 n 的子字符串从位置nnn开始:

<前><代码>与
--
函数replace_n(
varchar2 中的 str,
start_ 号,
count_ 数量

返回varchar2
作为
开始
返回
/*起始部分不变*/
子字符串(字符串,1,开始_)
/*替换:提取大小为n的子串*/
||翻译(
substr(str, start_ + 1, instr(str, '|', start_, count_-1) - start_)
, '|'
, '_'

/*剩余字符串*/
|| substr(str, instr(str, '|', start_, count_ - 1) + 1)
;
结尾;
--

db<>fiddle 此处

You can do it with plain substr/instr, but need to process edge cases carefully. Extract the part you need and replace all pipes in it. Then put everything together back.

with
--
function replace_n(
  str in varchar2,
  start_ in number,
  count_ in number
)
return varchar2
as
begin
  return
    /*Starting part unchanged*/
    substr(str, 1, start_)
    /*Replacement: locate n'th - 1 occurrence of pipe*/
    || translate(
      substr(str, start_ + 1, instr(str, '|', start_, count_-1) - start_)
      , '|'
      , '_'
    )
    /*Remaining string*/
    || substr(str, instr(str, '|', start_, count_ - 1) + 1)
  ;
end;
--
a(a) as (
  select
  'ABC|1234|mno|p|q|r|456|XYZ|QRS|TUV'
  from dual
)

select replace_n(a, 14, 3) as res
from a
| RES                                |
| :--------------------------------- |
| ABC|1234|mno|p_q_r|456|XYZ|QRS|TUV |

db<>fiddle here

UPD: Or if you were about replacement in the substring of size n starting from position nnn:

with
--
function replace_n(
  str in varchar2,
  start_ in number,
  count_ in number
)
return varchar2
as
begin
  return
    /*Starting part unchanged*/
    substr(str, 1, start_)
    /*Replacement: extract substring on size n*/
    || translate(
      substr(str, start_ + 1, instr(str, '|', start_, count_-1) - start_)
      , '|'
      , '_'
    )
    /*Remaining string*/
    || substr(str, instr(str, '|', start_, count_ - 1) + 1)
  ;
end;
--

db<>fiddle here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文