【问题标题】:Match a pattern using some condition and replace it with some string using regexp_replace in Oracle使用某些条件匹配模式并使用 Oracle 中的 regexp_replace 将其替换为某个字符串
【发布时间】:2020-09-16 14:46:33
【问题描述】:

我需要使用以下条件识别文本中的特定字符串:

*1。任何在其前后包含空格的字符串或

  1. 任何包含 . (点)作为前缀,空格作为后缀或

  2. 任何以空格为前缀和,(逗号)为后缀的字符串*

一旦找到,我需要用另一个字符串替换它,而不用替换上面提到的前缀和后缀。而这需要在 Oracle 的 pl/sql 代码中完成(最好使用 regexp_replace 函数)。

示例:

文字:'This, is a sample_text, which_needs_.to_be_replaced as per, the matching.criteria.defined above,'

替换字符串:'replaced'

输出:'This, replaced replaced replaced, which_needs_.replaced replaced replaced, replaced matching.criteria.replaced replaced'

我知道这是一个奇怪的例子,但实际的需求比这更奇怪。请指导我如何实现这一目标。

提前谢谢你。

【问题讨论】:

  • 我发现这很难用regexp_replace 处理,因此可能只是循环遍历字符。我想这不是你有问题的,对吗?您的问题仅仅是:“如果我使用regexp_replace 执行此操作,正则表达式必须是什么样的?”。是吗?
  • @ThorstenKettner 是的,没错。

标签: sql oracle regexp-replace


【解决方案1】:

与其尝试编写一个巨大的正则表达式,不如将字符串拆分为每个标记的行可能更容易。您可以通过调整任何 CSV-to-rows 方法来做到这一点。例如:

with rws as (
  select 'This, is a sample_text, which_needs_.to_be_replaced as per, the matching.criteria.defined above,' str from dual
), vals as (
  select regexp_substr(str,'[A-z_,]+(\.|\s)?', 1, level) str, level l
  from   rws
  connect by regexp_substr(str, '[^, .]+', 1, level) is not null
)
  select * from vals;

STR               L    
This,                  1 
is                     2 
a                      3 
sample_text,           4 
which_needs_.          5 
to_be_replaced         6 
as                     7 
per,                   8 
the                    9 
matching.             10 
criteria.             11 
defined               12 
above,                13

现在根据您的规则替换其中的每一个。您一次只处理一个令牌,因此很容易看出您正在正确替换哪个令牌。这使得正则表达式更易于编写和调试:

with rws as (
  select 'This, is a sample_text, which_needs_.to_be_replaced as per, the matching.criteria.defined above,' str from dual
), vals as (
  select regexp_substr(str,'[A-z_,]+(\.|\s)?', 1, level) str, level l
  from   rws
  connect by regexp_substr(str, '[^, .]+', 1, level) is not null
)
  select case 
           when l = 1 then str
           when substr ( str, -1, 1 ) = '.' then
             str
           else 
           regexp_replace (
             str,
             '^[A-z_]+',
             'replaced'
           )
       end replaced, l
  from   vals;

REPLACED        L    
This,                1 
replaced             2 
replaced             3 
replaced,            4 
which_needs_.        5 
replaced             6 
replaced             7 
replaced,            8 
replaced             9 
matching.           10 
criteria.           11 
replaced            12 
replaced,           13

然后你 listagg 将这些值重新组合在一起以获得最终的字符串:

with rws as (
  select 'This, is a sample_text, which_needs_.to_be_replaced as per, the matching.criteria.defined above,' str from dual
), vals as (
  select regexp_substr(str,'[A-z_,]+(\.|\s)?', 1, level) str, level l
  from   rws
  connect by regexp_substr(str, '[^, .]+', 1, level) is not null
), replaces as (
  select case 
           when l = 1 then str
           when substr ( str, -1, 1 ) = '.' then
             str
           else 
           regexp_replace (
             str,
             '[A-z_]+',
             'replaced'
           )
       end replaced, l
  from   vals
)
  select listagg ( replaced ) 
           within group ( order by l ) s
  from   replaces;

S                                                                                                                          
This, replaced replaced replaced, which_needs_.replaced replaced replaced, replaced matching.criteria.replaced replaced,

确保您进行彻底的测试!根据我的经验,当你有这样的复杂规则时,你会发现更多的例外/改进。因此,您可能不得不修改 case 表达式中的替换规则。

【讨论】:

    猜你喜欢
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 2019-08-27
    • 2021-04-29
    • 1970-01-01
    • 2014-12-13
    相关资源
    最近更新 更多