正则表达式背后的 pl/sql 否定查看

Posted

技术标签:

【中文标题】正则表达式背后的 pl/sql 否定查看【英文标题】:pl/sql negative look behind regex 【发布时间】:2015-02-19 13:12:58 【问题描述】:

我正在尝试在 pl/sql 中实现一个正则表达式,它排除任何以字符串开头的结果。

data:

exclude this: 3
include this: 3
3
cvxcvxcv3
34edfgdsfg3

Using this regexp:
(?<!exclude this: )3\d0(\s|$)

What I would expect to be returned is:
exclude this: 3   <-- nothing
include this: 3   <- 3
3                 <- 3
cvxcvxcv3         <- 3
34edfgdsfg3       <- the second 3 only
34edfgdsfg33      <- the last 3 only

在 notepad++ 中测试时效果很好,但是在 pl/sql 中实现时它不起作用。查看类似的问题,似乎 pl/sql 不完全支持负回溯,但有人知道类似的构造或解决此问题的方法吗?

【问题讨论】:

你能解释一下逻辑吗?无法对您的 notepad++ 代码进行逆向工程。 目前我有一个可以工作的正则表达式,但是在查看输出时,我发现当前表达式还不够,因为它返回的结果我想进一步过滤掉。例如,如果我目前有 3\d0(\s|$) 作为我的正则表达式。除了流氓结果(在这种情况下将是“排除此:3”的条目)之外,将返回的内容将是我想要的。这是我需要的额外过滤。 可能是我的问题不清楚。解释你希望如何看待其背后的输出和逻辑?所以你需要用简单的英语解释一下正则表达式背后的逻辑 用简单的英语来说,只要它后面没有任何其他东西,这个正则表达式就会查找数字 3。我想要的是还说“给我所有的数字 3,除了数字 3 前面有“排除这个:”的情况 - 也省略这些结果 编辑:当正则表达式在我的示例中构造它确实可以在记事本++中工作,但是 pl/sql 不以相同的方式支持正则表达式 - 我正在寻找答案 【参考方案1】:

虽然我不知道有任何通用技术可以通过 pl/sql 正则表达式来模拟负向回溯,但在您的特定情况下,一个解决方案是可能的:

([^e].13|[^x].12|[^c].11|[^l].10|[^u].9|[^d].8|[^e].7|[^ ].6|[^t].5|[^h].4|[^i].3|[^s].2|[^:].|[^ ]|^)3[^0-9]?(\s|$)

否定的lookbehind适用于文字。因此,必须匹配的第一个字符的所有禁止前缀以及它们的长度都是预先知道的。这允许将紧凑(嗯...)规范作为必须匹配的正则表达式。

并不是我会推荐最佳实践...或任何实践...

更新(处理建议):

目前的正则表达式识别匹配项,而不提供任何进一步的信息用于后处理。但是,您可以使用以下代码识别匹配的偏移量和禁止前缀的长度:

DECLARE
    s_data      VARCHAR2(4000); -- This will contain the line you match against
    s_matchpos  BINARY_INTEGER; -- Offset of the 'interesting' part (digit '3' under the various constraints) in s_data
    s_prefix    VARCHAR2(100);  -- The prefix part of the match
    s_re        VARCHAR2(4000); -- The regex
BEGIN
    s_re := '([^e].13|[^x].12|[^c].11|[^l].10|[^u].9|[^d].8|[^e].7|[^ ].6|[^t].5|[^h].4|[^i].3|[^s].2|[^:].|[^ ]|^)3[^0-9]?(\s|$)';
    s_prefix    := regexp_replace( s_data, s_re, '\1', 1, 1);   -- start at offset 1 of the data and find the first match
    s_matchpos  := regexp_instr( s_data, s_re ) + length(s_prefix);
END;

如上所述,不一定推荐为最佳实践...

【讨论】:

嗨,我认为这是有效的,但事实证明它没有。它似乎做的是做选择以及任何前面的字符(最多14个)。我只想选择“3”,其他什么都没有。 (Reg exp).

以上是关于正则表达式背后的 pl/sql 否定查看的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 中的正则表达式

pl/sql 正则表达式验证

在 oracle 中使用正则表达式查找 POBOX - PL/SQL

Python 正则表达式拆分 PL/SQL 指令

PL/SQL Oracle 正则表达式对于零的出现不起作用

如何在 Pl/SQL 中编写正则表达式匹配模式?