Oracle、Regexp、用分号分隔的字符串
Posted
技术标签:
【中文标题】Oracle、Regexp、用分号分隔的字符串【英文标题】:Oracle, Regexp, string separated via semicolons 【发布时间】:2017-12-20 11:55:09 【问题描述】:我有这个查询:
SELECT ROWNUM AS num_row,
REGEXP_SUBSTR(REPLACE('param1;param2;param3;;param5;;param7;;;param10;param11;param12;param13;param14;param15;',
';;',
'; ;'),
'[^;]+',
1,
level) AS par_value
FROM dual
CONNECT BY REGEXP_SUBSTR(REPLACE('param1;param2;param3;;param5;;param7;;;param10;param11;param12;param13;param14;param15;',
';;',
'; ;'),
'[^;]+',
1,
level) IS NOT NULL
输出:
1 param1
2 param2
3 param3
4
5 param5
6
7 param7
8
9 param10
10 param11
11 param12
12 param13
13 param14
14 param15
正如您已经看到(或未看到),在参数 7 和 10 之间应该有两个 NULL 参数,但是这个查询只返回一个。
如果我在 'param10' 之前多放一个分号或将 ';;param10' 更改为 '; ;param10' -> param10 在第 10 行,但这是我做不到的。
似乎';'的序列更长oracle 总是把分号的数量视为 -1 。
有人知道如何解决吗?
【问题讨论】:
仅供参考,这些是分号。:
是一个冒号。
仅供参考,感谢您的回答。真的有帮助:) 我想每个人都会理解这个问题
【参考方案1】:
如果我是你,我会通过在 connect by 子句中使用 regexp_count 来简化事情(看起来你的参数总是以分号结尾,所以无论有多少分号,你都想遍历字符串很多次)。
另外,[^<characters>]
的方法不处理空值,因此您需要切换到(.*?)(;|$)
的模式 - 即。零个或多个字符后跟一个分号,然后只选择第一个表达式 (`.*?)。
这意味着你可以这样做:
WITH sample_data AS (SELECT 'param1;param2;param3;;param5;;param7;;;param10;param11;param12;param13;param14;param15;' str FROM dual)
SELECT LEVEL AS num_row,
REGEXP_SUBSTR(REPLACE(str,
';;',
'; ;'),
'[^;]+',
1,
level) AS par_value,
REGEXP_SUBSTR(str, '(.*?)(;)', 1, LEVEL, NULL, 1) new_str
FROM sample_data
CONNECT BY LEVEL <= regexp_count(str, ';');
NUM_ROW PAR_VAL NEW_STR
---------- ------- -------
1 param1 param1
2 param2 param2
3 param3 param3
4
5 param5 param5
6
7 param7 param7
8
9 param10
10 param11 param10
11 param12 param11
12 param13 param12
13 param14 param13
14 param15 param14
15 param15
注意,如果尾随分号实际上意味着后面有一个空参数,那么您需要切换到(.*?)(;|$)
的模式(即零个或多个字符后跟分号或结尾字符串),另外你需要在 regexp_count 结果中加一:
WITH sample_data AS (SELECT 'param1;param2;param3;;param5;;param7;;;param10;param11;param12;param13;param14;param15;' str FROM dual)
SELECT LEVEL AS num_row,
REGEXP_SUBSTR(REPLACE(str,
';;',
'; ;'),
'[^;]+',
1,
level) AS par_value,
REGEXP_SUBSTR(str, '(.*?)(;|$)', 1, LEVEL, NULL, 1) new_str
FROM sample_data
CONNECT BY LEVEL <= regexp_count(str, ';') + 1;
NUM_ROW PAR_VAL NEW_STR
---------- ------- -------
1 param1 param1
2 param2 param2
3 param3 param3
4
5 param5 param5
6
7 param7 param7
8
9 param10
10 param11 param10
11 param12 param11
12 param13 param12
13 param14 param13
14 param15 param14
15 param15
16
【讨论】:
以上是关于Oracle、Regexp、用分号分隔的字符串的主要内容,如果未能解决你的问题,请参考以下文章
使用 regexp_substr 在 Oracle 中按空格和字符拆分字符串作为分隔符
Oracle Regexp 根据第一次出现的分隔符拆分字符串
Oracle REGEXP_SUBSTR |获取两个分隔符之间的字符串