在 Pl/SQL 中,我需要替换类似的东西;
'MOUSE RAT <FONT COLOR="#FF0000">DOG</FONT> CAT ELEPHANT'
和
'MOUSE RAT ????????????????????????????????? CAT ELEPHANT'
基本上我需要用占位符“?”替换 HTML 标记和中间的所有内容。等于我要替换的字符串的长度。好消息是标签永远是字体标签。
REGEXP_REPLACE 会这样做吗?
如果那么图案是什么样的?
REGEXP_REPLACE()
替换一个模式,因此虽然它对于查找要替换的内容很有用,但不能用相同长度的内容替换已删除的字符串。
以下内容将替换 HTML:
regexp_replace(str, '</?FONT.*>')
然后,您需要在删除字符串的长度上加上问号,即删除之前的字符串长度减去现在的字符串长度。
不幸的是,我不确定是否有解决此问题的好方法。您必须使用一个字符来通知您,一旦字符串被替换,这就是问号所在的位置。像下面这样的东西会起作用:
replace( regexp_replace(str, '</?FONT.*>', '?')
, '?'
, lpad( '?'
, length(str) - length(regexp_replace(str, '</?FONT.*>', '?')) - 1
, '?'
)
)
不过我真的不喜欢它......如果整个事情都是 HTML,那么使用适当的解析器会更容易更好,然后你可以替换一个节点中的所有数据。
虽然我喜欢PL/SQL,但我不建议这样做。PL/SQL强大的数据操作工具,但对解析不太方便。这是 Java 存储过程可以更高效的示例。尤其是当您必须多次重构代码时。
也REGEX_REPLACE
适用于VARCHARs
(最大大小 32KB),而您可能需要使用 CLOB。
我写了一个函数,它比 Ben 的代码更容易理解,但可能效率较低,当然也不那么优雅。我还没有决定使用哪个,你觉得呢?
FUNCTION REPLACE_WITH_PLACEHOLDER(IN_STRING IN VARCHAR2, START_STRING IN VARCHAR2, END_STRING IN VARCHAR2, PLACEHOLDER IN VARCHAR2) RETURN VARCHAR2
IS
OUT_STRING VARCHAR2(32767);
START_POSITION BINARY_INTEGER := 0;
END_POSITION BINARY_INTEGER;
SEARCH_LENGTH BINARY_INTEGER;
SEARCH_STRING VARCHAR2(500);
REPLACE_STRING VARCHAR2(500);
BEGIN
OUT_STRING := IN_STRING;
START_POSITION := INSTR(OUT_STRING,START_STRING);
WHILE START_POSITION > 1
LOOP
END_POSITION := INSTR(OUT_STRING,END_STRING,START_POSITION) + LENGTH(END_STRING);
IF END_POSITION > 0
THEN
SEARCH_LENGTH := (END_POSITION - START_POSITION);
SEARCH_STRING := SUBSTR(OUT_STRING,START_POSITION,SEARCH_LENGTH);
REPLACE_STRING := LPAD(PLACEHOLDER,SEARCH_LENGTH,PLACEHOLDER);
OUT_STRING := REPLACE(OUT_STRING,SEARCH_STRING,REPLACE_STRING);
ELSE
EXIT;
END IF;
START_POSITION := INSTR(OUT_STRING,START_STRING);
END LOOP;
RETURN OUT_STRING;
END REPLACE_WITH_PLACEHOLDER;