它看起來像通過反向引用到一個函數的REG EX功能是行不通的(至少在我的測試和缺乏發現的內任何在那裏的工作正常(雖然有這個link,但它很難稱之爲參考)
但你可以做到這一點,但它會慢慢處理,但它應該工作。基於這個樣本從這個link在
declare
l_foo varchar2(4000);
searchString varchar2(4000) ;
searchPattern varchar2(4000) ;
/*type matchItem is object(
position number ,
matchedPattern varchar2(4000));*/
type matched is table of varchar2(100);
l_foo2 matched;
function f_test(i_t varchar2) return varchar2
is
begin
dbms_output.put_line('given parameter: ' || i_t);
return upper(i_t);
end f_test;
function getNMatch(
str in varchar2,
pat in varchar2,
occr in number ,
flags in varchar2 := null
) return varchar2 is
pos_match_begin number;
pos_match_end number;
str_used varchar2(4000);
begin
pos_match_begin := regexp_instr (
str, --
pat,
1, -- start position
occr, -- occurance
0, -- return option
flags
);
pos_match_end := regexp_instr (
str, --
pat,
1, -- start position
occr, -- occurance
1, -- return option
flags
);
if (pos_match_begin >= 0 and pos_match_end > 0) THEN
str_used := substr(str, pos_match_begin, pos_match_end - pos_match_begin);
ELSE
str_used := null;
end if;
return str_used ;
end getNMatch;
function match (
str in varchar2,
pat in varchar2,
flags in varchar2 := null) return matched is
ret matched;
i number ;
regCount number ;
begin
regCount := regexp_count(str, pat) ;
ret := matched();
for i in 1 .. regCount LOOP
ret.extend() ;
ret(i) := getNMatch(str, pat , i, flags);
END LOOP;
return ret;
end match;
function reMatch (
str in varchar2,
pat in varchar2,
flags in varchar2 := null) return varchar2
is
ret matched;
str_out varchar2(4000);
begin
str_out := str;
ret := match(str,pat,flags);
for i in REVERSE 1..ret.count loop
str_out := regexp_replace(str_out, pat, f_test(ret(i)),1, i);
end loop;
return str_out ;--ret;
end reMatch;
begin
searchString := 'http://www.scoach.com/${asset_type}/${ISIN}?eventtarget=${target}ANDeventvalue=${target_value}';
searchPattern:= '\$\{([[:alpha:]_]+)\}';
l_foo := reMatch(searchString,
searchPattern);
--this example will call a custom function that will auto-change the entire string as defined by you
dbms_output.put_line(l_foo);
--here is another example that will 'allow' you to use the count of the table's position as a pseudo backreference to pull out your items and scrub them as desired
l_foo2 := match(searchString ,searchPattern);
dbms_output.put_line('\4/\3,\2: \1 || ' || f_test(l_foo2(4)) || '/' || l_foo2(3) || ',' || l_foo2(2) || ': ' || l_foo2(1));
end;
集SERVEROUTPUT導致
given parameter: ${target_value}
given parameter: ${target}
given parameter: ${ISIN}
given parameter: ${asset_type}
http://www.scoach.com/${ASSET_TYPE}/${ISIN}?eventtarget=${TARGET}ANDeventvalue=${TARGET_VALUE}
given parameter: ${target_value}
\4/\3,\2: \1 || ${TARGET_VALUE}/${target},${ISIN}: ${asset_type}
這是在11gR1中完成。你可以看到我只是循環遍歷這個結果並將結果放入一個varchar2表中,然後從那裏用函數結果逐行進行替換。 (請注意,有可能是更有效的方式來做到這一點,我沒有追求效率,而只是爲了讓它工作)
哦,很酷謝謝! PS性能不是一個大問題。 – christian 2010-11-17 11:00:21
@christian太棒了,希望這對你有用,如果確實不忘記標記爲正確答案! – Harrison 2010-11-17 13:04:24