oracle否定向前看正则表达式不起作用

时间:2014-02-27 16:58:33

标签: sql regex database oracle negative-lookahead

我有一个在Java中运行良好的正则表达式,但不适用于Oracle。

它会查找<a href="abcd" etc etc xyz >标记,其中xyz不在元素块中。

<a href="abcd" etc etc xyz > = not match
<a href="abcd" etc etc > = match

Regx:(<[a][\s]+[^>]*[href]="[^>](?:(?!xyz).)*?)(>)

但同样的事情在Oracle中返回null

select I from atable
where regexp_like (column, '(<[a][\s]+[^>]*[href]="[^>](?:(?!xyz).)*?)(>)')

有什么想法吗?

让我澄清一下这个问题。其实我需要完成这个。 假设我们有一个文本列'datacolumn',它包含html语法数据。我需要找到字符串

<a href="abcd" etc etc > 

并将其替换为

<a href="abcd" etc etc xyz> 

如果数据列中已有字符串,我不应该插入另一个xyz,而只是保留它。因此,如果列有这样的数据

,请说明
<a href="abcd" etc etc > asdf </a> etc etc <a href="efgh" etc etc xyz> 

然后我希望将其替换为

<a href="abcd" etc etc xyz> asdf </a> etc etc <a href="efgh" etc etc xyz>

如果我不使用负向前看,我最终会像这样插入双xyz

<a href="abcd" etc etc xyz> asdf </a> etc etc <a href="efgh" etc etc xyz xyz>

我正在使用

REGEXP_REPLACE(datacolunm,'(<[a][\s]+[^>]*[href]="[^>](?:(?!xyz).)*?)(>)')','\1 xyz \3')

但由于不支持负向前瞻或我的reqex不兼容oracle,我找不到任何匹配。这虽然适用于Java。

1 个答案:

答案 0 :(得分:1)

没有关于Oracle SQL中与reg表达式相关的负向前瞻功能的文档。

因此,在这里使用解码语句来重现负前瞻功能:

SELECT
    DECODE(
        REGEXP_SUBSTR(
            REGEXP_SUBSTR( '<a href="abcd" etc etc >', '<a\s[^>]*href="abcd"[^>]*>' ),
            'xyz'
        ),
        'xyz',
        NULL,
        REGEXP_SUBSTR( '<a href="abcd" etc etc >', '<a [^>]*href="abcd"[^>]*>' )
    )
FROM dual; 

<强>解释

  1. 使用此函数检查我们是否具有带有href =“abcd”属性的“a”元素:

    REGEXP_SUBSTR('<a href="abcd" etc etc >','<a\s[^>]*href="abcd"[^>]*>')

  2. 搜索此元素中是否存在字符串模式'xyz'。

    REGEXP_SUBSTR( calculation 1 ,'xyz')

  3. 解码

    if 'xyz' exists in element, then NULL otherwise element.