删除除img src和href

时间:2016-04-28 11:24:54

标签: regex oracle replace

除了img src和href之外,我如何删除字符串中的html标签。我尝试了如下,但它删除了所有标记。

SELECT 
    REGEXP_REPLACE('lorem <em>ipsum</em><img src="/folder/file.jpg" /> ipsum','<.*?>') 
FROM DUAL;

结果:lorem ipsum(我需要像这样的lorem /folder/file.jpg ipsum)

1 个答案:

答案 0 :(得分:1)

您需要保护<img代码src<a代码href属性的内容不被删除。以下正则表达式仅保留原始数据中html标记的这些部分:

REGEXP_REPLACE (
    REGEXP_REPLACE (
        REGEXP_REPLACE (
            'lorem <a class="interference" href="http://www.example.com"><em>ipsum</em><img src="/folder/file.jpg" /> ipsum</a> whatever'
          , '<a[^>]*? href="([^"]+)"[^>]*>|<img[^>]*? src="([^"]+)"[^>]*>|<a[^>]*? href=''([^'']+)''[^>]*>|<img[^>]*? src=''([^'']+)''[^>]*>'
          , '<<\1\2>>'
        )
      , '([^<])<[^<][^>]*>'
      , '\1'
    )
  , '<<([^>]+)>>'
  , ' \1 '
)

<强> 解释

  • 要保护的属性值包含在双尖括号中:<<>>。 匹配允许标记名称和目标属性之间的干扰属性以及由双引号或单引号分隔的属性值。
  • 目标属性用单引号或双引号括起来。因此,在每次比赛中,将填充恰好1个捕获组。因此,它们的序列可以插入替换模式'<<\1\2>>'而不需要任何进一步的消歧逻辑。
  • 包含在单个尖括号中的所有字符序列都将被替换
  • 删除双角括号<<>>

<强> 注意事项

  • 一般情况下,强烈建议不要使用regexen代替正确的解析。它更容易出错,更不灵活和可扩展;维护和调试的噩梦。

  • 匹配不允许目标属性值中的转义双引号。 这不应该是srchref的问题;但是,期望遇到诸如titledata-...

  • 等目标属性的问题
  • 替换不应干扰文字中的数据,因为<>需要在html中表示为实体,除非用作语法元素。但是,对于带有cdata部分的xhtml数据,这不会有效,其中会出现<<>>。如果这可能是一个问题,请测试原始字符串的出现次数。

<强>补编

如果您希望在有效标记中保留所述属性值,请使用目标属性保护标记。为此,请使用以下内容:

REGEXP_REPLACE (
    REGEXP_REPLACE (
        REGEXP_REPLACE (
            'lorem <a href="http://www.example.com"><em>ipsum</em><img src="/folder/file.jpg" /> ipsum</a> whatever'
          , '(<a href|<img src|</a|</img)'
          , '<\1'
        )
      , '([^<])<[^<][^>]*>'
      , '\1'
    )
  , '<(<a href|<img src|</a|</img)'
  , '\1'
)

<强> 解释

  • 要保护的标记以附加<为前缀。
  • 所有不以双<<开头的代码都会被替换
  • <<序列的后替代。 替换应用于与前缀
  • 相同的上下文中

<强> 注意事项

  • 一般警告仍然存在:最好不要使用regexen作为解析器的替身

  • 为了使结果保持有效html,需要保留匹配的开始和结束标记。不幸的是,这种匹配不能用oracle regexp faclities来解释(并且对于支持递归的其他正则表达式引擎来说非常复杂)。因此,所有结束aimg代码都会保留。

虽然后者很少在野外发生(除非它是xhtml),但前者会导致<a name="...标签出现问题。

  • 将删除元素名称和目标属性之间具有干扰属性的标记。最常见的是,这适用于classdata-属性。由于4个支持的变体(标记名a / img,单引号/双引号分隔符)和潜在的干扰属性,因此适应此案例会使正则表达式再次变得更复杂:

-

REGEXP_REPLACE (
    REGEXP_REPLACE (
        REGEXP_REPLACE (
            REGEXP_REPLACE(
                  'lorem <a href="http://www.example.com"><em>ipsum</em><img src="/folder/file.jpg" /> ipsum</a> whatever'
                , '</(a|img)>'
                , '<</\1>'
            )
          , '<(a )[^>]*?(href="[^"]+"|href=''[^'']+'')[^>]*>|<(img )[^>]*?(src="[^"]+"|src=''[^'']+'')[^>]*>'
          , '<<\1\2\3\4>'
        )
      , '([^<])<[^<][^>]*>'
      , '\1'
    )
  , '<(<a href|<img src|</a|</img)'
  , '\1'
)