Regexp_substr未按预期工作

时间:2016-09-20 16:47:43

标签: sql oracle11g

所以,我有一个简单的SQL,如:

select 
REGEXP_SUBSTR (randomcol, '[^|]+', 1, 2)
||'|'||       REGEXP_SUBSTR (randomcol, '[^|]+', 1, 3)
||'|'||       REGEXP_SUBSTR (randomcol, '[^|]+', 1, 4)
from table1 where ADDTL_DETAIL_INFO is not null and module_key='01-07-2016 00:00:00/2212/    1';

我们的想法是获取randomcol列中存在的管道分隔值,其中存在的值为:

~custom|HELLO1||HELLO3

所以我需要像HELLO1这样的值,空格(因为第二个管道和第三个管道之间没有值)和HELLO3。

但是当我运行上面的查询时,它返回为:

HELLO1|HELLO3|

并且白色空间消失了。我需要这个空白区域来保留。那么我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

'[^|]+'形式的正则表达式不适用于NULL列表元素,应该避免使用!有关详情,请参阅此帖子:Split comma separated values to columns in Oracle

请改用此表格:

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

其中可以理解为“以逗号或行尾结束第5次出现的第一个字符组”。

因此,对于第4个元素,您将使用它来保留元素3中的NULL(假设您想要通过单独的元素构建它,而不是仅仅从第一个分隔符到结尾之后从字符中获取字符串):

...
REGEXP_SUBSTR (addtl_detail_info, '(.*?)(\||$)', 1, 2) ||
REGEXP_SUBSTR (addtl_detail_info, '(.*?)(\||$)', 1, 3) ||
REGEXP_SUBSTR (addtl_detail_info, '(.*?)(\||$)', 1, 4)
...

你知道,这可能会更容易。只需抓住第一个管道后的所有内容:

SQL> select REGEXP_replace('~custom|HELLO1||HELLO3', '^.*?\|(.*)', '\1') result
   from dual;

RESULT
--------------
HELLO1||HELLO3

SQL>

括号括起你想要“记住”的内容,替换字符串用“\ 1”引用第一个记住的组。