我有一个名为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.ABC
,JOJ.TTT.123
,JOJ.TTT.452
和JOJ.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}。我怎样才能得到我想要的结果?
由于
答案 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)
虽然正则表达式中的.
可用于此目的,但它也会匹配您不想要的内容,因为它是通配符。使用\.
匹配文字.
。您还可以使用LEVEL
和CONNECT 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;
如果您有多个列并希望全部返回它,那么它会变得有点笨拙:
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将返回id
和comment1
值的交叉联接。
顺便说一句,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