带Connect by的正则表达式

时间:2019-06-26 19:23:07

标签: oracle

我有这个查询:

select regexp_substr('1,2,3,4,5','[^,]+',1,level) 
from test1 
connect by instr('1,2,3,4,5',',',1,level-1)>0;

请帮助我理解此查询,尤其是一个级别的用法,以及by和level-1的连接。

2 个答案:

答案 0 :(得分:0)

LEVEL和CONNECT BY用于生成序列,请参见以下简单示例:

select level
from dual
connect by level < 10;

LEVEL
=======
1
2
3
4
5
6
7
8
9

instr('1,2,3,4,5', ',' , 1, level-1) > 0计算用逗号分隔的元素的数量,也许此版本更易于理解,其作用相同:

select regexp_substr('1,2,3,4,5','[^,]+',1,level) 
from dual 
connect by LEVEL <= REGEXP_COUNT('1,2,3,4,5', ',')+1;

LEVEL <= REGEXP_COUNT('1,2,3,4,5', ',')+1instr('1,2,3,4,5', ',' , 1, level-1) > 0表示“运行5次”。

因此,您的选择基本上是

的快捷方式
select regexp_substr('1,2,3,4,5','[^,]+', 1, 1) from dual union all 
select regexp_substr('1,2,3,4,5','[^,]+', 1, 2) from dual union all 
select regexp_substr('1,2,3,4,5','[^,]+', 1, 3) from dual union all 
select regexp_substr('1,2,3,4,5','[^,]+', 1, 4) from dual union all 
select regexp_substr('1,2,3,4,5','[^,]+', 1, 5) from dual;

答案 1 :(得分:0)

@Wernfried的回答很好,但是您应该知道'[^,]+'格式的正则表达式存在很大的风险,人们经常将其视为解析分隔字符串的示例。

仅当存在列表的所有元素时,此选项才有效。为了让您大开眼界,请尝试将第二个元素设为NULL:

select regexp_substr('1,,3,4,5', '[^,]+', 1, 3) from dual;

REGEXP_SUBSTR('1,,3,4,5','[^,]+',1,3)
-------------------------------------
4   

1 row selected.

什么? '4'绝对是该列表的第3个元素,!如您所见,没有处理NULL。

请使用以下格式的REGEXP_SUBSTR来处理NULL列表元素:

select regexp_substr('1,,3,4,5','(.*?)(,|$)', 1, 3, NULL, 1) from dual;


REGEXP_SUBSTR('1,,3,4,5','(.*?)(,|$)',1,3,NULL,1)
-------------------------------------------------
3              

1 row selected.

正则表达式定义了2组,一组可选的任何字符,后跟逗号或行尾。 REGEXP_SUBSTR的参数 说返回此比赛的第三个实例的第一组。