2016-04-13 2 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; 

Обратите внимание, что вы делаете не хотите изменить один в группе, (.|$); в этом контексте это оператор 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, и положение элемента в списке имеет важное значение. Рассмотрим это, когда 2-й элемент равен NULL. Результаты показывают, что 2-й элемент - это «str 3», где действительно 2-й элемент равен 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

+0

Хорошая точка. Первоначальный запрос OP обрабатывает это, поэтому первый запрос в моем ответе тоже - хотя ему все еще нужно обрезать пробелы. Я задавался вопросом, почему шаблоны не были одинаковыми в исходном запросе, и это, вероятно, почему. Ваш шаблон избавляется от 'rtrim()' в версии OP, что делает жизнь проще. –

Смежные вопросы