2010-11-15 88 views
2

我想對字符串中的值進行一些計算並最終替換它們。 Oracles正則表達式看起來不錯,但是在所有計算結果中得到了評估。所以我想知道在將它傳遞給函數之前我是否可以評估它?是否可以使用函數regexp_replace?

set serveroutput on 

declare 
    l_foo varchar2(4000); 

    function f_test(i_t varchar2) return varchar2 
    is 
    begin 
    dbms_output.put_line('given parameter: ' || i_t); 
    return upper(i_t); 
    end; 
begin 
    l_foo := regexp_replace(
    'http://www.scoach.com/${asset_type}/${ISIN}?eventtarget=${target}ANDeventvalue=${target_value}' 
    ,'\$\{([[:alpha:]_]+)\}' 
    ,f_test('\1') 
); 

    dbms_output.put_line(l_foo); 
end; 

使你像一個結果:

given parameter: \1 
http://www.scoach.com/asset_type/ISIN?eventtarget=targetANDeventvalue=target_value 
PL/SQL procedure successfully completed. 

回答

2

它看起來像通過反向引用到一個函數的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表中,然後從那裏用函數結果逐行進行替換。 (請注意,有可能是更有效的方式來做到這一點,我沒有追求效率,而只是爲了讓它工作)

+0

哦,很酷謝謝! PS性能不是一個大問題。 – christian 2010-11-17 11:00:21

+0

@christian太棒了,希望這對你有用,如果確實不忘記標記爲正確答案! – Harrison 2010-11-17 13:04:24

相關問題