select rtrim(regexp_substr (str, '[^|]*(.|$)', 1, level), '|') ASPLIT
from
(select 'str 1|str 2|str 3' as str from dual)
connect by level <= length (regexp_replace (str, '[^|]+')) + 1
str 1
str 2
str 3
如何更改解析器分隔符','?
'str 1,str 2,str 3'
答案 0 :(得分:1)
您只需更改模式中的分隔符:
select rtrim(regexp_substr (str, '[^,]*(.|$)', 1, level), ',') ASPLIT
from
(select 'str 1, str 2, str 3' as str from dual)
connect by level <= length (regexp_replace (str, '[^,]+')) + 1;
请注意,您不想要更改分组中的(.|$)
;在那种情况下,它是一个OR运算符而不是文字字符。
在子字符串中使用与替换中相同的模式更简单(但请注意Gary_W关于使用此模式丢失空值的警告):
select trim(regexp_substr (str, '[^,]+', 1, level)) ASPLIT
from (select 'str 1, str 2, str 3' as str from dual)
connect by level <= length (regexp_replace (str, '[^,]+')) + 1;
ASPLIT
-------------------
str 1
str 2
str 3
但是因为你的逗号后面有空格,你需要消除它们;最简单的方法是去除带有修剪的前导和尾随空格。这也显示了connect by
限制的变化但是可以工作(再次注意关于此模式的警告):
select trim(regexp_substr (str, '[^,]+', 1, level)) ASPLIT
from (select 'str 1, str 2, str 3' as str from dual)
connect by regexp_substr (str, '[^,]+', 1, level) is not null;
ASPLIT
-------------------
str 1
str 2
str 3
答案 1 :(得分:1)
我必须指出,如果列表中有NULL元素并且列表中元素的位置很重要,使用格式'[^,]+'
的正则表达式解析字符串将产生无效结果。考虑第二个元素为NULL的情况。结果使它看起来第二个元素是&#39; str 3&#39;第二个元素真的是NULL。
SQL> select trim(regexp_substr (str, '[^,]+', 1, level)) ASPLIT
from (select 'str 1,, str 3' as str from dual)
connect by level <= length (regexp_replace (str, '[^,]+')) + 1;
ASPLIT
-------------
str 1
str 3
这是另一种处理NULL列表元素的方法:
SQL> select trim(regexp_substr (str, '(.*?)(,|$)', 1, level, NULL, 1)) ASPLIT
from (select 'str 1,, str 3' as str from dual)
connect by level <= regexp_count(str, ',') + 1;
ASPLIT
-------------
str 1
str 3
SQL>
有关详情,请参阅此帖子:Split comma separated values to columns in Oracle