2016-04-13 181 views
-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 

STR 1
STR 2
STR 3解析字符串爲Oracle

如何改變解析器分離器 ''?

體的STR 1,STR 2,STR 3'

回答

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

我必須指出,使用格式'[^,]+'的正則表達式解析字符串會給無效結果如果列表中有一個NULL元素並且元素在列表中的位置很重要。考慮第二個元素爲NULL的情況。結果看起來第二個元素是'str 3',其中第二個元素是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 

下面是處理空列表元素的另一種方式:

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

+0

好一點。 OP的原始查詢處理了這個問題,因此我的答案中的第一個查詢也做到了 - 儘管它仍然需要修剪空白。我想知道爲什麼這些模式在原始查詢中不一樣,這可能是爲什麼。你的模式擺脫了OP版本中的'rtrim()',這使得生活更簡單。 –