我需要帮助从文本中删除外部标记。因为它不是文本而是Html标记,它不能按照给定的解决方案工作: 原文:
<HIDE><HIDE>Anti-</HIDE></HIDE>Skull
我需要从文本中删除外部和标记。
可能变成:
<HIDE>Anti-</HIDE>Skull
答案 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
正则表达式将与简单情况相匹配,但您会发现很难(或不可能)正确处理第二种和第三种情况。