2017-06-14 32 views
4

我想用OF替换OF单词的实例。我只希望这能够用完整的单词来工作。因此,不在L_OF,DOF,OFZ,DOFD,OF_L等上。Oracle上的regexp_replace完整的单词

我的代码工作如下,但最后一个字符串除外。

它返回:

("OF"*OF + 2) 

...相反:

("OF"*"OF" + 2) 

我怎样才能得到它的上一个工作中呢?

with stg as 
(
select '(ofof+ol)' str from dual union all 
select '(oof+ol+of)' from dual union all 
select '(*of + 2)'  from dual union all 
select '(of*of + 2)' from dual 
) 
select str, 
     regexp_replace(upper(str), '(\W|^)(OF)(\W|$)', '\1"OF"\3') as str2 
from stg 
+0

问题是缺少posix正则表达式中的lookarounds。我想要得到你想要的东西,你必须把它放在一个plsql过程中,循环或嵌套regexp_replace,然后在另一个替换中删除多余的引号。 – RLOG

回答

0

这是太长的评论。我不知道解决方案,但我理解这个问题。你会发现'of of'更容易,但'of**of'更容易。

问题是定义第一个单词的字符不用于定义第二个单词。正则表达式似乎需要特殊字符,例如“^”表示“之前匹配后的第一个字符”。我不知道是否存在。

3

以下是一种方法 - 使用递归查询(需要Oracle 11.2或更高版本)。不要期望它快。

with stg as 
(
    select '(ofof+ol)' str from dual union all 
    select '(oof+ol+of)' from dual union all 
    select '(*of + 2)'  from dual union all 
    select '(of*of + 2)' from dual 
), 
rec (str, lvl, new_str) as 
(
    select str, 1, upper(str) 
    from stg 
    union all 
    select str, lvl + 1, 
     regexp_replace(new_str, '(\W|^)(OF)(\W|$)', '\1"OF"\3', 1, lvl) 
    from rec 
    where regexp_instr(new_str, '(\W|^)(OF)(\W|$)', 1, lvl) > 0 
) 
select str, new_str 
from rec 
where regexp_instr(new_str, '(\W|^)(OF)(\W|$)', 1, lvl) = 0 
; 

STR   NEW_STR   
------------ ------------------ 
(ofof+ol) (OFOF+OL)   
(oof+ol+of) (OOF+OL+"OF")  
(*of + 2) (*"OF" + 2)  
(of*of + 2) ("OF"*"OF" + 2) 
+0

谢谢 - 这很好! –