如何从正则表达式oracle中的文本中删除重复的html标记

时间:2017-05-31 10:00:58

标签: sql oracle

我需要帮助从文本中删除外部标记。因为它不是文本而是Html标记,它不能按照给定的解决方案工作:  原文:

<HIDE><HIDE>Anti-</HIDE></HIDE>Skull

我需要从文本中删除外部和标记。

可能变成:

<HIDE>Anti-</HIDE>Skull

2 个答案:

答案 0 :(得分:1)

只是结束我们在评论中讨论的内容:

SELECT regexp_replace('<HIDE><HIDE>Anti-</HIDE></HIDE>Skull', '(<.*>)\1+', '\1') AS checktext FROM dual

regexp_replace将与正则表达式匹配的部分输入替换为另一个字符串。如果您使用(<.*>)\1+作为正则表达式,它将匹配以<>开头和结尾的字符串,然后再次使用相同的内容多次。使用\1作为替换字符串将使用该字符串的一个副本替换整个事物。如果您无法理解正则表达式的工作原理,请阅读“捕获组”。

请阅读MT0的答案,以便在您的html变得更复杂时采用更强大的方法。

答案 1 :(得分:0)

您可以使用XML函数执行此操作:

WITH data ( xmlstring ) AS (
  SELECT '<html><body><HIDE><HIDE>Anti-</HIDE></HIDE>Skull</body></html>' FROM DUAL
)
SELECT UPDATEXML(
         xml,
         '//HIDE/HIDE/..',
         XMLQUERY( '//HIDE/HIDE' PASSING xml RETURNING CONTENT )
       ).getClobVal() AS updatedXML
FROM   ( SELECT XMLTYPE( xmlstring ) AS xml FROM data );

<强>输出

<html><body><HIDE>Anti-</HIDE>Skull</body></html>

您还应该能够使用更通用的XPath '//*[name()=../name()]/..';但是,XMLQUERY成功解析时,UPDATEXML没有。

<强>更新

WITH data ( xmlstring ) AS (
  SELECT '<HIDE><HIDE>Anti-</HIDE></HIDE>Skull' FROM DUAL
)
SELECT SUBSTR(
         updatedXML,
         7,
         LENGTH( updatedXML ) - 13
       )
FROM   (
  SELECT UPDATEXML(
           xml,
           '//HIDE/HIDE/..',
           XMLQUERY( '//HIDE/HIDE' PASSING xml RETURNING CONTENT )
         ).getClobVal() AS updatedXML
  FROM   (
    SELECT XMLTYPE( '<root>' || xmlstring || '</root>' ) AS xml
    FROM data
  )
);

更新2

在使用正则表达式之前,您应该了解限制 - a regular expression cannot parse arbitrary HTML,但只能在有限的子集上使用。在这种情况下,它将不匹配属性或匹配正确的标记级别(您应该使用XML解析器):

WITH data ( html ) AS (
  SELECT '<HIDE><HIDE>Anti-</HIDE></HIDE>Skull' FROM DUAL UNION ALL
  SELECT '<HIDE><HIDE>first</HIDE></HIDE>between<HIDE><HIDE>second</HIDE></HIDE>' FROM DUAL UNION ALL
  SELECT '<HIDE><HIDE>before<HIDE><HIDE>inner</HIDE></HIDE>after</HIDE></HIDE>outer' FROM DUAL
)
SELECT REGEXP_REPLACE(
         html,
         '<([A-Za-z][A-Za-z0-9-]*)><\1>(.*)</\1></\1>',
         '<\1>\2</\1>'
       )
FROM   data;

<强>输出

<HIDE>Anti-</HIDE>Skull
<HIDE>first</HIDE></HIDE>between<HIDE><HIDE>second</HIDE>
<HIDE>before<HIDE><HIDE>inner</HIDE></HIDE>after</HIDE>outer

正则表达式将与简单情况相匹配,但您会发现很难(或不可能)正确处理第二种和第三种情况。