解析Oracle的字符串正则表达式

时间:2016-04-13 11:05:29

标签: oracle plsql

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'

2 个答案:

答案 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