REGEXP_LIKE,用于5个字符的子字符串中任意位置的字符

时间:2019-03-01 15:05:42

标签: sql oracle regexp-like

我有一个旧的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 个答案:

答案 0 :(得分:3)

你不能做这样的事情吗?

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

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

如果您要专门查找除1Y以外的全部Ns的5个字符,那么我希望您的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或多个Ns后面跟Y是非常不常见的。

当然,还有明显的地方:

where regexp_like(bar, 'YNNNN|NYNNN|NNYNN|NNNYN|NNNNY')

答案 1 :(得分:1)

如其他地方所述,您发布的代码段实际上并没有归零到您要检查的5个字符上。不管是因为它被错误地转录,还是因为代码从未按预期工作,或者是其他原因,我不能说。但是按照书面规定,它仅表示字符串中的某个地方是一个Y,其他字符将其包围,因此总共至少有5个字符。

WHY does this match NNNNN

将满足该条件,因为字符串中的第3个字符是Y,并被其他一些字符包围,因此总数至少为5。

如果您的意思是您总是看 last 个5个字符-如果NY s的tre块位于字符串的末尾-那么如果您从每个模式中删除结尾的%,您的原始代码就会起作用。

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

通常,这似乎不太适合正则表达式解决方案IMO

答案 2 :(得分:1)

尝试以下WHERE条款:

>>> a = {}
>>> a['some','tuple'] = 'value'
>>> a
{('some', 'tuple'): 'value'}

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

where regexp_like(regexp_substr(bar,'[YN]{5}'),'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');

答案 3 :(得分: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})%');