2017-06-14 71 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

謝謝 - 這很好! –