【问题标题】:Oracle plsql rtf varchar2 field to plain text formatOracle plsql rtf varchar2 字段转纯文本格式
【发布时间】:2011-09-10 01:11:36
【问题描述】:

我需要将 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

我尝试按字符解析 RTF 字符串,但这不是一个非常聪明的解决方案。 任何 RTF 文本的 PL/SQL 实用程序方法都是最好的方法。 有本地解决方案吗?任何想法如何转换 rtf 文本?

感谢您分享您的时间和想法。

【问题讨论】:

    标签: oracle text plsql rtf


    【解决方案1】:

    显然这可以通过 Oracle Text 完成 - 请参阅 this AskTom question

    【讨论】:

    【解决方案2】:

    我用简单的 PL/SQL 实现了它。 Based on this SQL source,但完全重写。 (反斜杠+撇号在这里混淆了代码着色)

    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;
    /
    

    【讨论】:

      【解决方案3】:

      我没有评论 CLS 帖子的名誉,但我想 建议行

        if vPos1 = 0 then
      

      应该改为

        if nvl(vPos1,0)=0 then
      

      否则,如果 RTF 格式不正确,函数将永远卡在 while 循环中

      再见 安德烈亚斯

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-21
        • 2019-03-22
        相关资源
        最近更新 更多