与其尝试编写一个巨大的正则表达式,不如将字符串拆分为每个标记的行可能更容易。您可以通过调整任何 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 表达式中的替换规则。