看起来将反向引用传递到 reg ex 函数中的函数中是行不通的(至少在我的测试中,并且找不到任何可以正常工作的东西(尽管有这个)link http://database.itags.org/oracle/190340/但很难称之为参考)
但你可以这样做,但处理速度会很慢,但它应该可以工作。我基于这个样本link http://www.adp-gmbh.ch/blog/2005/december/22.html
将服务器输出设置为打开
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;
这导致
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 表中,然后使用函数结果从那里进行逐行替换。 (请注意,可能有更有效的方法可以做到这一点,我并不是在追求效率,而是只是为了让它发挥作用)