1

我有一个旧的 Access 查询,我正在尝试将其转换为 Oracle SQL。它的一部分查看可以包含一大堆文本的字符串,而字符串的另一部分是一系列五个字符,例如:

NNNNN

我想要做的是找到这些字符中的任何一个,Y但只有在特定格式中,在 5 个字符内。例如,整个字符串可能是:

The quick brown fox jumps over the lazy dog NNNNN

我不想退货,因为这五个NNNNN不包含Y.

当前查询执行以下操作:

SELECT *
FROM foo
WHERE
(
bar LIKE '%Y____%' OR 
bar LIKE '%_Y___%' OR
bar LIKE '%__Y__%' OR 
bar LIKE '%___Y_%' OR
bar LIKE '%____Y%'
)

但是,我认为这可以通过单个 REGEXP_LIKE 语句更好地实现。我怎么能这样做?

4

4 回答 4

3

你不能做这样的事情吗?

where bar like '%Y%' and length(b) >= 5

这基本上是您的逻辑,不需要正则表达式。

如果您正在寻找 5 个字符,除了 1Y 之外都是 N,那么我希望您的like解决方案是:

where bar like '%YNNNN%' or bar like '%NYNNN%' or . . . 

一个简单的正则表达式版本对我来说并不明显。

一种接近的方法是:

where regexp_like(bar, '[YN]{5}') and    -- has a substring with 5 characters, all of which are Y and N
      not regexp_like(bar, 'Y[N]{0-3}Y'  -- has no substring with Y followed by 0-3 Ns and another Y

这可能会在其他文本中的某些单词上失败。但是,Y 后跟 0 个或多个 N 后跟 Y 在英语单词中是非常不寻常的。

当然,也有明显的:

where regexp_like(bar, 'YNNNN|NYNNN|NNYNN|NNNYN|NNNNY')
于 2019-03-01T15:07:33.613 回答
1

如其他地方所述,您发布的代码片段实际上并未将您要检查的 5 个字符归零。无论是因为它被错误地转录,还是因为代码从未按预期工作,或者其他什么,我不能说。但正如所写的那样,它只说字符串中的某处是一个被其他字符包围的 Y,因此总共至少有 5 个字符。

WHY does this match NNNNN

将满足该标准,因为字符串中的第三个字符是由其他字符包围的 Y,因此总数至少为 5。

如果你的意思是你总是在看最后N5 个字符——如果s 和s 的tre 块Y位于字符串的末尾——那么如果它%从每个模式中删除尾随,你的原始代码就可以工作。

在这种情况下,获取字符串的最后 5 个字符(使用当前 DBMS 提供的子字符串函数)并Y在该子字符串中查找任何字符可能会更容易。在这种情况下,如果您真的想使用正则表达式,您只需寻找匹配子字符串中任何位置的“Y”,但这可能有点过头了。

一般来说,这似乎不太适合正则表达式解决方案 IMO

于 2019-03-01T15:27:53.877 回答
1

试试这个 WHERE 条款:

where regexp_like(regexp_substr(bar,'[YN]{5}'),'Y')    

下面的示例显示它仅返回表“foo”中(Ys 或 Ns)的字符串包含“Y”的那些记录。

select * from foo;
BAR
--------------------------------------------------
The quick brown fox jumps over the lazy dog YNNNN
The quick brown fox jumps over the lazy dog NYNNN
The quick brown fox jumps over the lazy dog NNYNN
The quick brown fox jumps over the lazy dog NNNYN
The quick brown fox jumps over the lazy dog NNNNY
The quick brown fox jumps over the lazy dog NNNNN
The quick brown fox jumps over the lazy dog NNNNN
The quick brown fox jumps over the lazy dog NNNNN
The quick brown fox jumps over the lazy dog NNNNN
The quick brown fox jumps over the lazy dog NNNNN

10 rows selected.
select * from foo where regexp_like(regexp_substr(bar,'[YN]{5}'),'Y');
BAR
--------------------------------------------------
The quick brown fox jumps over the lazy dog YNNNN
The quick brown fox jumps over the lazy dog NYNNN
The quick brown fox jumps over the lazy dog NNYNN
The quick brown fox jumps over the lazy dog NNNYN
The quick brown fox jumps over the lazy dog NNNNY

5 rows selected.
于 2019-03-01T16:42:59.987 回答
0

用户要求所有相似字符连续出现 5 次,其中一个替换 Y 而不仅仅是 N。这是解决方案之一:

select * from foo where
regexp_like(bar,'%Y(A{4}|B{4}|C(4)....Z{4}%)') or
regexp_like(bar,'%(A{4}|B{4}|C(4)....Z{4})Y%') or
regexp_like(bar,'%(A{1}|B{1}|C(1)....Z{1})Y(A{3}|B{3}|C{3)....Z{3})%') or
regexp_like(bar,'%(A{2}|B{2}|C(2)....Z{2})Y(A{2}|B{2}|C{2}....Z{2})%') or
regexp_like(bar,'%(A{3}|B{3}|C(3)....Z{3})Y(A{1}|B{1}|C{1}....Z{1})%');
于 2019-03-02T15:54:15.730 回答