我在oracle中使用REPLACE
函数替换字符串中的值,如;
SELECT REPLACE('THE NEW VALUE IS #VAL1#','#VAL1#','55') from dual
所以可以替换一个值,但20+以上,我应该使用20 + REPLACE
函数还是有更实用的解决方案。
欢迎所有想法。
答案 0 :(得分:39)
即使这个帖子是旧的,也是谷歌的第一个,所以我将使用正则表达式发布与此处实现的函数相当的Oracle。
比嵌套的replace()快得多,而且更干净。
在给定表格的字符串列中用'd'替换字符串'a','b','c'
select regexp_replace(string_col,'a|b|c','d') from given_table
对于带有'或'运算符的几个静态模式,它只不过是正则表达式。
小心regexp特殊字符!
答案 1 :(得分:21)
how to replace multiple strings together in Oracle接受的答案建议使用嵌套的REPLACE
语句,我认为没有更好的方法。
如果你要大量使用它,你可以考虑编写自己的函数:
CREATE TYPE t_text IS TABLE OF VARCHAR2(256);
CREATE FUNCTION multiple_replace(
in_text IN VARCHAR2, in_old IN t_text, in_new IN t_text
)
RETURN VARCHAR2
AS
v_result VARCHAR2(32767);
BEGIN
IF( in_old.COUNT <> in_new.COUNT ) THEN
RETURN in_text;
END IF;
v_result := in_text;
FOR i IN 1 .. in_old.COUNT LOOP
v_result := REPLACE( v_result, in_old(i), in_new(i) );
END LOOP;
RETURN v_result;
END;
然后像这样使用它:
SELECT multiple_replace( 'This is #VAL1# with some #VAL2# to #VAL3#',
NEW t_text( '#VAL1#', '#VAL2#', '#VAL3#' ),
NEW t_text( 'text', 'tokens', 'replace' )
)
FROM dual
这是包含一些替换标记的文本
如果您的所有令牌具有相同的格式('#VAL' || i || '#'
),则可以省略参数in_old
并改为使用循环计数器。
答案 2 :(得分:20)
答案 3 :(得分:4)
这是一篇很老的帖子,但我最终使用了Peter Lang的想法,并采用了类似但却不同的方法。这是我做的:
CREATE OR REPLACE FUNCTION multi_replace(
pString IN VARCHAR2
,pReplacePattern IN VARCHAR2
) RETURN VARCHAR2 IS
iCount INTEGER;
vResult VARCHAR2(1000);
vRule VARCHAR2(100);
vOldStr VARCHAR2(50);
vNewStr VARCHAR2(50);
BEGIN
iCount := 0;
vResult := pString;
LOOP
iCount := iCount + 1;
-- Step # 1: Pick out the replacement rules
vRule := REGEXP_SUBSTR(pReplacePattern, '[^/]+', 1, iCount);
-- Step # 2: Pick out the old and new string from the rule
vOldStr := REGEXP_SUBSTR(vRule, '[^=]+', 1, 1);
vNewStr := REGEXP_SUBSTR(vRule, '[^=]+', 1, 2);
-- Step # 3: Do the replacement
vResult := REPLACE(vResult, vOldStr, vNewStr);
EXIT WHEN vRule IS NULL;
END LOOP;
RETURN vResult;
END multi_replace;
然后我可以像这样使用它:
SELECT multi_replace(
'This is a test string with a #, a $ character, and finally a & character'
,'#=%23/$=%24/&=%25'
)
FROM dual
这使得我可以使用任何字符/字符串的任何字符/字符串。
我在博客上写了一篇关于此事的帖子。
答案 4 :(得分:4)
如果您的所有源和替换字符串只有一个字符长,您只需使用TRANSLATE
函数:
SELECT translate('THIS IS UPPERCASE', 'THISUP', 'thisup')
FROM DUAL
有关详细信息,请参阅the Oracle documentation。
答案 5 :(得分:2)
我已经通过varchar2表作为参数创建了一个通用的多替换字符串Oracle函数。 varchar将替换为table的位置rownum值。
例如:
Text: Hello {0}, this is a {2} for {1}
Parameters: TABLE('world','all','message')
返回:
Hello world, this is a message for all.
您必须创建一个类型:
CREATE OR REPLACE TYPE "TBL_VARCHAR2" IS TABLE OF VARCHAR2(250);
功能是:
CREATE OR REPLACE FUNCTION FN_REPLACETEXT(
pText IN VARCHAR2,
pPar IN TBL_VARCHAR2
) RETURN VARCHAR2
IS
vText VARCHAR2(32767);
vPos INT;
vValue VARCHAR2(250);
CURSOR cuParameter(POS INT) IS
SELECT VAL
FROM
(
SELECT VAL, ROWNUM AS RN
FROM (
SELECT COLUMN_VALUE VAL
FROM TABLE(pPar)
)
)
WHERE RN=POS+1;
BEGIN
vText := pText;
FOR i IN 1..REGEXP_COUNT(pText, '[{][0-9]+[}]') LOOP
vPos := TO_NUMBER(SUBSTR(REGEXP_SUBSTR(pText, '[{][0-9]+[}]',1,i),2, LENGTH(REGEXP_SUBSTR(pText, '[{][0-9]+[}]',1,i)) - 2));
OPEN cuParameter(vPos);
FETCH cuParameter INTO vValue;
IF cuParameter%FOUND THEN
vText := REPLACE(vText, REGEXP_SUBSTR(pText, '[{][0-9]+[}]',1,i), vValue);
END IF;
CLOSE cuParameter;
END LOOP;
RETURN vText;
EXCEPTION
WHEN OTHERS
THEN
RETURN pText;
END FN_REPLACETEXT;
/
用法:
TEXT_RETURNED := FN_REPLACETEXT('Hello {0}, this is a {2} for {1}', TBL_VARCHAR2('world','all','message'));
答案 6 :(得分:2)
感谢您的回答。除了在调用中指定翻译之外,您还可以使用如下所示的游标来执行此操作。
create or replace function character_substitutions (input_str varchar2)
return varchar2
as
v_result VARCHAR2(4000);
cursor c_translate_table is
select '&' as symbol_to_replace, 'amp' as symbol_in_return_string from dual
union all
select '/' as symbol_to_replace, '_' as symbol_in_return_string from dual
union all
select '"' as symbol_to_replace, 'in' as symbol_in_return_string from dual
union all
select '%' as symbol_to_replace, 'per' as symbol_in_return_string from dual
union all
select '.' as symbol_to_replace, '_' as symbol_in_return_string from dual;
begin
v_result := input_str;
for r_translate in c_translate_table loop
v_result := REPLACE( v_result, r_translate.symbol_to_replace, r_translate.symbol_in_return_string);
end loop;
return v_result;
end;
/