похоже, что передача обратной ссылки в функцию внутри функции reg ex не сработает (по крайней мере, в моем тесте и из-за отсутствия поиска чего-либо там, что работает должным образом (хотя была эта ссылка * 1002)* но это трудно назвать ссылкой)
Но вы можете сделать это, но это будет медленная за медленной обработкой, но она должна работать. Я основал этот пример из этой ссылки
установить выход сервера на
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, а затем построчно выполните замену на результаты функции (обратите внимание, что, возможно, есть более эффективные способы сделать это, я не стремился к эффективности, а скорее просто чтобы получить егоработа)