多次返回一个模式

时间:2015-02-13 05:02:59

标签: sql oracle

我有一个名为comment的列,可以包含多达5次的特定模式,我想返回所有这些模式。这是我在我的作品中的价值:

  

oijdwe wbjcwe sbr(' JOJ.TTT.ABC',test)sdfjksj dlkfjs lkf qweiuh   (' JOJ.TTT.123',test)oiiqwd m lskc qu i(' JOJ.TTT.452',test)ksd   sdfskq azx(' JOJ.TTT.ACD5',测试)

我想返回以下值:JOJ.TTT.ABCJOJ.TTT.123JOJ.TTT.452JOJ.TTT.ACD5

使用以下声明时

 select 
     regexp_substr(comment,'JOJ.T{3}.{4}',1,1)
     ,regexp_substr(comment,'JOJ.T{3}.{4}',1,2)
     ,regexp_substr(comment,'JOJ.T{3}.{4}',1,3)
     ,regexp_substr(comment,'JOJ.T{3}.{4}',1,4)
     ,regexp_substr(comment,'JOJ.T{3}.{4}',1,5)
 from blabla

如果模式是JOJ.TTT.XXX,它可以正常工作,但是如果" TTT。"之后有4个字符则不行。我知道这是因为我正在使用{4}。我怎样才能得到我想要的结果?

由于

3 个答案:

答案 0 :(得分:2)

使用[^']+匹配,直到下一个'

 select 
      regexp_substr(comment_,q'!JOJ.T{3}[^']+!',1,1)   a,
      regexp_substr(comment_,q'!JOJ.T{3}[^']+!',1,2)   b,
      regexp_substr(comment_,q'!JOJ.T{3}[^']+!',1,3)   c,
      regexp_substr(comment_,q'!JOJ.T{3}[^']+!',1,4)   d,
      regexp_substr(comment_,q'!JOJ.T{3}[^']+!',1,5)   e
 from blabla;

我已将comment更改为comment_,因为comment是Oracle中的保留关键字。

答案 1 :(得分:1)

虽然正则表达式中的.可用于此目的,但它也会匹配您不想要的内容,因为它是通配符。使用\.匹配文字.。您还可以使用LEVELCONNECT BY,因此您无需明确写出对REGEXP_SUBSTR()的多次调用:

WITH x AS (
  SELECT 'oijdwe wbjcwe sbr (''JOJ.TTT.ABC'', test) sdfjksj dlkfjs lkf qweiuh (''JOJ.TTT.123'', test) oiiqwd m lskc qu i (''JOJ.TTT.452'', test) ksd sdfskq azx (''JOJ.TTT.ACD5'', test)' AS comment1
    FROM dual
)
SELECT REGEXP_SUBSTR(comment1,'JOJ\.TTT\.[A-Z0-9]+', 1, LEVEL)
  FROM x
CONNECT BY REGEXP_SUBSTR(comment1,'JOJ\.TTT\.[A-Z0-9]+', 1, LEVEL) IS NOT NULL;

See SQL Fiddle here.

如果您有多个列并希望全部返回它,那么它会变得有点笨拙:

WITH x AS (
  SELECT 1 AS id, 'oijdwe wbjcwe sbr (''JOJ.TTT.ABC'', test) sdfjksj dlkfjs lkf qweiuh (''JOJ.TTT.123'', test) oiiqwd m lskc qu i (''JOJ.TTT.452'', test) ksd sdfskq azx (''JOJ.TTT.ACD5'', test)' AS comment1
    FROM dual
   UNION ALL
  SELECT 2 AS id, 'oijdwe wbjcwe sbr (''JOJ.TTT.ABC'', test) sdfjksj dlkfjs lkf qweiuh (''JOJ.TTT.123'', test) oiiqwd m lskc qu i (''JOJ.TTT.452'', test) ksd sdfskq azx (''JOJ.TTT.ACD5'', test)' AS comment1
    FROM dual
)
SELECT id, REGEXP_SUBSTR(comment1,'JOJ\.TTT\.[A-Z0-9]+', 1, LEVEL)
  FROM x
CONNECT BY REGEXP_SUBSTR(comment1,'JOJ\.TTT\.[A-Z0-9]+', 1, LEVEL) IS NOT NULL
    AND PRIOR id = id
    AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL;

See SQL Fiddle here.如果没有PRIOR条款,Oracle将返回idcomment1值的交叉联接。

顺便说一句,COMMENT是一个Oracle保留字,上述查询在11g r2中不能使用名为comment的列。这就是我使用comment1代替的原因。

或者,您可以使用[^'']+代替[A-Z0-9]+但是根据您的示例数据,我不确定您的需求是什么。

答案 2 :(得分:0)

我找到了解决方法

select 
    regexp_substr(comment,'JOJ.T[^'']+',1,1)
    ,regexp_substr(comment,'JOJ.T[^'']+',1,2)
    ,regexp_substr(comment,'JOJ.T[^'']+',1,3)
    ,regexp_substr(comment,'JOJ.T[^'']+',1,4)
    ,regexp_substr(comment,'JOJ.T[^'']+',1,5) 
from blabla