Voici une façon de procéder - avec une requête récursive (nécessite Oracle 11.2 ou supérieur). Ne vous attendez pas à ce que ce soit rapide.
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)