替换标记之间的特定子字符串

时间:2015-02-26 22:33:19

标签: sql regex oracle plsql tags

我有以下HTML文档片段:

<ol>
    <li>some text</li>
    <li>some <strong>more</strong> text</li>
    <li>some more text</li>
</ol>
<ul>
    <li>even more text</li>
    <li>...</li>
</ul>

我想要实现的是将<li><ol>之间</ol>的所有##li##实例替换为</li>##/li## <li> </li> } <ul></ul>之间的<ol> ##li##some text##/li## ##li##some <strong>more</strong> text##/li## ##li##some more text##/li## </ol> <ul> <li>even more text</li> <li>...</li> </ul> l_html_new := REGEXP_REPLACE( l_html_old , '<regex1 here>' , '##li##' ); l_html_new := REGEXP_REPLACE( l_html_new , '<regex2 here>' , '##/li##' ); 的所有实例都应保持不变:

declare
  --
  c_crlf char(2) := chr(13)||chr(10);
  --
  l_html_old varchar2(4000);
  l_html_new varchar2(4000);
  l_pattern  varchar2(400);
  --
begin
  l_html_old :=   
      '<ol>'||c_crlf
  ||    '<li>some text</li>'||c_crlf
  ||    '<li>some <strong>more</strong> text</li>'||c_crlf
  ||    '<li>some more text</li>'||c_crlf
  ||  '</ol>'||c_crlf
  ||  '<ul>'||c_crlf
  ||    '<li>even more text</li>'||c_crlf
  ||    '<li>...</li>'||c_crlf
  ||  '</ul>'
  ;
  --
  l_pattern := '<(li)>(.*?)<(\/li)>([^>]*)(?=(<li>.*?<\/li>[^>]*)*(?:[^>]*<\/ol>))';
  --
  l_html_new := 
    REGEXP_REPLACE(
      l_html_old                  --source_string
    , l_pattern                   --pattern
    , '##$1##$2##$3##$4'          --replace_string
    , 1                           --position
    , 0                           --occurrence
    , 'im'                        --match_parameter
  );
  --
  dbms_output.put_line(l_html_new);
  --
end;

虽然这主要是一个正则表达式问题,但如果我感兴趣的话,我将在存储过程中在Oracle XE 11g2上使用Oracle的REGEXP_REPLACE函数。

我很想发布到目前为止我所尝试的内容,但说实话,我完全迷失了这个。

可以在两次通过中执行此操作:

{{1}}

更新

@cfqueryparam,你的解决方案很有趣,因为它似乎正是我在JS中所需要的。但是,我无法在Oracle中使用它。 这就是我所拥有的:

{{1}}

这只输出没有替换的原始字符串。 反向引用可能存在问题,但我认为这不是至关重要的。由于根本没有发生替换,我认为没有任何匹配。

我将尝试找出JS和Oracle之间的处理差异。

2 个答案:

答案 0 :(得分:1)

我没有要测试的ORACLE数据库,但是我可以用javascript来演示你可以利用的东西。

演示:http://jsfiddle.net/knjv9zjp/1/

<(li)>(.*?)<(\/li)>([^>]*)(?=(<li>.*?<\/li>[^>]*)*(?:[^>]*<\/ol>))

我确实想要考虑LI标签的属性,这很容易。

此版本将捕获属性,并将它们放入开始哈希

<(li[^>]*)>(.*?)<(\/li)>([^>]*)(?=(<li>.*?<\/li>[^>]*)*(?:[^>]*<\/ol>))

此版本将识别可能存在的属性,而不捕获它们

<(li)[^>]*>(.*?)<(\/li)>([^>]*)(?=(<li>.*?<\/li>[^>]*)*(?:[^>]*<\/ol>))

答案 1 :(得分:0)

我认为你需要的只是简单的Replace():

SELECT REPLACE(
'<ol>
  <li>some text</li>
  <li>some <strong>more</strong> text</li>
  <li>some more text</li>
</ol>
<ul>
  <li>even more text</li>
  <li>...</li>
 </ul>', '<li>', '###li###')
FROM dual
/

输出:

<ol>
   ###li###some text</li>
   ###li###some <strong>more</strong> text</li>
   ###li###some more text</li>
</ol>
<ul>
   ###li###even more text</li>
   ###li###...</li>
</ul>