我需要将VARCHAR2字段的格式丰富的文本转换为纯文本。
例如:
{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil Tahoma;}{\f1\fnil\fcharset0 Tahoma;}}
{\colortbl ;\red0\green0\blue255;}
\viewkind4\uc1\pard\cf1\lang1031\b\f0\fs16 NUMBER_A\cf0\b0\f1 *\cf1\b\protect NUMBER_B\cf0\b0\protect0\f0\par
}
应转换为:
NUMBER_A * NUMBER_B
我试图通过char解析RTF字符串char,但这不是一个非常聪明的解决方案。 任何RTF文本的PL / SQL实用程序方法都是最好的方法。 有原生解决方案吗?任何想法如何转换rtf文本?
分享您的时间和想法。
答案 0 :(得分:2)
显然,这可以通过Oracle Text完成 - 请参阅this AskTom question
答案 1 :(得分:1)
我没有拒绝评论CLS的帖子,但我想 告知该行
if vPos1 = 0 then
应更改为
if nvl(vPos1,0)=0 then
否则,如果RTF格式不正确,该功能将永远停留在while循环中
再见 安德烈亚斯(Andreas)
答案 2 :(得分:0)
我用简单的PL / SQL做到了。 Based on this SQL source,但已完全重写。 (反斜杠+ Apostrofe在这里混淆了代码的着色)
CREATE OR REPLACE FUNCTION Rtf2Txt
(
pRtf varchar2
)
return nvarchar2 is
/*
Converts RTF text to TXT format by removing headers, commands, and formatting
*/
vPos1 int;
vPos2 int;
vPos3 int;
vPos4 int;
vTmp int;
vText varchar2(4000);
begin
vText := pRtf;
if vText is null then
return vText;
end if;
-- Remove outer { and } pair
vPos1 := instr(vText, '{', +1); -- The first {
vPos2 := instr(vText, '}', -1); -- The last }
if vPos1 > 0 and vPos2 > 0 then
vText := substr(vText, vPos1 +1, vPos2 - vPos1 -1);
end if;
-- Remove inner { and } pairs
while 1 = 1 loop
vPos2 := instr(vText, '}', +1); -- The first }
vPos1 := instr(vText, '{', (length(vText) - vPos2) *-1 -1); -- The last { before the found }
if vPos1 > 0 and vPos2 > 0 and vPos1 < vPos2 then
vText := substr(vText, 1, vPos1 -1) || substr(vText, vPos2 +1, length(vText) - vPos2);
else
exit;
end if;
end loop;
-- Cleaning up
vText := replace(vText, '\pard', '');
vText := replace(vText, chr(13), '');
vText := replace(vText, chr(10), '');
vText := replace(vText, '\par', chr(13));
while length(vText) > 0 and substr(vText, 1, 1) IN (' ', CHR(13), CHR(10)) loop
vText := substr(vText, 2, length(vText) -1);
end loop;
while length(vText) > 0 and substr(vText, length(vText), 1) IN (' ', CHR(13), CHR(10)) loop
vText := substr(vText, 1, length(vText) -1);
end loop;
-- Remove \ commands and replace \'XX charactercoding
vPos2 := 1;
while 1 = 1 loop
vPos1 := instr(vText, '\', vPos2);
if vPos1 = 0 then
exit;
end if;
if substr(vText, vPos1 +1, 1) = '\' then -- Skip \\ escape sequence, when present
vPos2 := vPos1 +2;
continue;
end if;
if substr(vText, vPos1 +1, 1) = '''' then -- Decode \' hex sequence
vTmp := to_number(substr(vText, vPos1 +2, 2), 'xx');
vText := substr(vText, 1, vPos1 -1) ||chr(vTmp)|| substr(vText, vPos1 +4, length(vText) - vPos1 -3);
vPos2 := vPos1 +1;
continue;
end if;
-- Skip \anything sequence
vPos2 := instr(vText, '\', vPos1 +1); -- The next \
vPos3 := instr(vText, ' ', vPos1 +1); -- The next ' '
vPos4 := instr(vText, chr(13), vPos1 +1); -- The next Enter
if vPos4 > 0 and vPos4 < vPos3 then
vPos3 := vPos4;
end if;
if vPos2 = 0 and vPos3 = 0 then
vPos3 := length(vText);
end if;
if vPos2 > 0 and (vPos2 < vPos3 or vPos3 = 0) then
vText := substr(vText, 1, vPos1 -1) || substr(vText, vPos2, length(vText) - vPos2 +1);
vPos2 := vPos1;
end if;
if vPos3 > 0 and (vPos3 < vPos2 or vPos2 = 0) then
vText := substr(vText, 1, vPos1 -1) || substr(vText, vPos3 +1, length(vText) - vPos3);
vPos2 := vPos1;
end if;
end loop;
return vText;
end;
/