Использование regexp_substr в записи с разделителями табуляции с пробелами в полях

Используя Oracle 12c, как я могу использовать regexp_substr для разделения записей с разделителями табуляции, поля которых могут содержать пробелы? Запись имеет четыре поля. Третье поле содержит слова с пробелами.

Я использую это как ссылку:Oracle Regex< /а>

Вот мой запрос

with tab_delimited_record as
 (select 'Field1    Field2  This is field3 and contains spaces  Field4' as record_with_fields from dual) 
 select record_with_fields,
        regexp_substr('\S+',1,3) as field3a, -- Expect ==>This is field3...
        regexp_substr('\t+',1,3) as field3b, -- Expect==>This is field3...
        regexp_substr('[[::space::]]+',1,3) as field_3c -- Another version
  from  tab_delimited_record

Желаемые результаты

ЗАПИСЬ_С_ПОЛЯМИ

Поле1 Поле2 Это поле3 и содержит пробелы Поле4

ПОЛЕ3

Это field3 и содержит пробелы


person zundarz    schedule 15.10.2018    source источник


Ответы (3)


Я считаю, что вы ищете что-то вроде этого. Обратите внимание, что этот пример возвращает все поля для примера, но, конечно, вы можете просто выбрать field3, если это все, что вам нужно. CTE строит строку с полями, разделенными табуляцией. Затем запрос использует regex_substr для получения n-й (4-й аргумент) строки символов, за которой следует TAB или конец строки.

with tab_delimited_record(record_with_fields) as (
  select 'Field1'||chr(09)||'Field2'||chr(09)||'This is field3 and contains spaces'||chr(09)||'Field4' from dual
) 
select record_with_fields,
       regexp_substr(record_with_fields, '(.*?)('||chr(09)||'|$)', 1, 1, null, 1) as field_1, 
       regexp_substr(record_with_fields, '(.*?)('||chr(09)||'|$)', 1, 2, null, 1) as field_2, 
       regexp_substr(record_with_fields, '(.*?)('||chr(09)||'|$)', 1, 3, null, 1) as field_3,
       regexp_substr(record_with_fields, '(.*?)('||chr(09)||'|$)', 1, 4, null, 1) as field_4
from  tab_delimited_record;
person Gary_W    schedule 15.10.2018

Вы не можете буквально инертить '\t' при работе с Oracle SQL. Вам нужно разбить строку, использовать chr(09) (вкладка ascii), а затем построить строку. Попробуйте это

with tab_delimited_record as
 (select 'Field1'||chr(09)||'Field2'||chr(09)||'This is field3 and contains spaces'||chr(09)||'Field4' as record_with_fields from dual) 
    select record_with_fields,
        regexp_substr(record_with_fields,'(\S+)\s+(\S+)\s+(.+)\s+',1,1,'',3) as field3a, -- Expect ==>This is field3...
        regexp_substr(record_with_fields,'(\S+)'||chr(09)||'(\S+)'||chr(09)||'(.+)\s+',1,1,'',3) as field3b, -- Expect==>This is field3...
        regexp_substr(record_with_fields,'(\S+)[[:space:]]+(\S+)[[:space:]]+(.+)[[:space:]]+',1,1,'',3) as field_3c -- Another version
  from  tab_delimited_record
person stack0114106    schedule 15.10.2018

Другая версия регулярного выражения:

with tab_delimited_record(record_with_fields) as (
  select 'Field1'||chr(09)||'Field2'||chr(09)||'This is field3 and contains spaces'||chr(09)||'Field4' from dual
) 
select record_with_fields,
       regexp_substr(record_with_fields, '[^'||chr(09)||']+', 1, 3) as field_3
from  tab_delimited_record;
person Marcin Szczepaniak    schedule 03.01.2020