Замена символов в строке между двойными кавычками - PullRequest
2 голосов
/ 10 марта 2020

Я хотел бы заменить запятые в моих строках между динамическими c позициями (ie. Между двойными кавычками). Обратите внимание, что в моих строках не будет более двух двойных кавычек, если это имеет значение.

Мой пример:

'randomtext,123,"JEAN SEBASTIEN, GUY, DANIEL",sun'

Желаемый вывод:

'randomtext,123,"JEAN SEBASTIEN GUY DANIEL",sun'

До сих пор я пробовал что-то с REGEXP_REPLACE(), смешанным с INSTR(), но не смог ничего сделать.

Cheers

Ответы [ 2 ]

3 голосов
/ 10 марта 2020

Предполагая, что вы работаете с CSV, возможно, у вас также будут вложенные двойные кавычки в соответствии с этим примером данных:

CREATE TABLE test_data ( value ) AS
SELECT 'randomtext,123,"JEAN SEBASTIEN, GUY, DANIEL",sun' FROM DUAL UNION ALL
SELECT 'randomtext,123,"A, ""BC"", D",sun' FROM DUAL;

Вы можете использовать регулярное выражение ^(.*?)("([^\"]|\\")+")(.*)$, чтобы соответствовать условиям до, внутри кавычек и после, а затем замените запятые только в средних частях:

SELECT value,
       REGEXP_SUBSTR( value, '^(.*?)("([^\"]|"")+")(.*)$', 1, 1, NULL, 1 )
       || REPLACE(
            REGEXP_SUBSTR( value, '^(.*?)("([^\"]|"")+")(.*)$', 1, 1, NULL, 2 ),
            ','
          )
       || REGEXP_SUBSTR( value, '^(.*?)("([^\"]|"")+")(.*)$', 1, 1, NULL, 4 ) replaced_value
FROM   test_data

Какие выводятся:

VALUE                                            | REPLACED_VALUE                                
:----------------------------------------------- | :---------------------------------------------
randomtext,123,"JEAN SEBASTIEN, GUY, DANIEL",sun | randomtext,123,"JEAN SEBASTIEN GUY DANIEL",sun
randomtext,123,"A, ""BC"", D",sun                | randomtext,123,"A ""BC"" D",sun               

дБ <> fiddle здесь


Обновление

Если вам нужно обрабатывать несколько заключенных в кавычки терминов в строке (с вложенными кавычками):

CREATE TABLE test_data ( value ) AS
SELECT 'randomtext,123,"JEAN SEBASTIEN, GUY, DANIEL",sun' FROM DUAL UNION ALL
SELECT 'randomtext,123,"A, ""BC"", D",sun' FROM DUAL UNION ALL
SELECT 'E,"F, G",H,"I, ""J""", K' FROM DUAL UNION ALL
SELECT 'L,M,N' FROM DUAL;

Затем вы можете использовать рекурсивное условие факторинга подзапроса:

WITH replacements( value, prefix, suffix ) AS (
  SELECT value,
         REGEXP_SUBSTR( value, '^(.*?)("([^\"]|"")+"|$)(.*)$', 1, 1, NULL, 1 )
         || REPLACE(
              REGEXP_SUBSTR( value, '^(.*?)("([^\"]|"")+"|$)(.*)$', 1, 1, NULL, 2 ),
              ','
            ),
         REGEXP_SUBSTR( value, '^(.*?)("([^\"]|"")+"|$)(.*)$', 1, 1, NULL, 4 )
  FROM   test_data
UNION ALL
  SELECT value,
         prefix
         || REGEXP_SUBSTR( suffix, '^(.*?)("([^\"]|"")+"|$)(.*)$', 1, 1, NULL, 1 )
         || REPLACE(
              REGEXP_SUBSTR( suffix, '^(.*?)("([^\"]|"")+"|$)(.*)$', 1, 1, NULL, 2 ),
              ','
            ),
         REGEXP_SUBSTR( suffix, '^(.*?)("([^\"]|"")+"|$)(.*)$', 1, 1, NULL, 4 )
  FROM   replacements
  WHERE  suffix IS NOT NULL

)
SELECT value,
       prefix AS replaced_value
FROM   replacements
WHERE  suffix IS NULL;

, которое выдает:

VALUE                                            | REPLACED_VALUE                                
:----------------------------------------------- | :---------------------------------------------
L,M,N                                            | L,M,N                                         
randomtext,123,"JEAN SEBASTIEN, GUY, DANIEL",sun | randomtext,123,"JEAN SEBASTIEN GUY DANIEL",sun
randomtext,123,"A, ""BC"", D",sun                | randomtext,123,"A ""BC"" D",sun               
E,"F, G",H,"I, ""J""", K                         | E,"F G",H,"I ""J""", K                        

db <> fiddle здесь

3 голосов
/ 10 марта 2020

Короткий и чистый.

with t(str) as (select 'randomtext,123,"JEAN SEBASTIEN, GUY, DANIEL",sun' from dual)
select regexp_replace(str,'(^[^"]*|[^"]*$)|,','\1') as result
from   t

-

+------------------------------------------------+
|                     RESULT                     |
+------------------------------------------------+
| randomtext,123,"JEAN SEBASTIEN GUY DANIEL",sun |
+------------------------------------------------+

SQL Скрипка

Дополнительно -
Короткий и чистый универсальный c версия

with t(str) as 
(
             select 'Well,you,went,uptown,riding,in,your,limousine' from dual
  union all  select 'With,your,fine,"Park, Avenue, clothes"' from dual
  union all  select 'You,had,the,"Dom, Perignon",in,your,hand,"And, the, spoon",up,your,nose' from dual
  union all  select '"And, when, you",wake,"up, in, the, morning"' from dual
  union all  select '"With, your, head, on, fire"' from dual
  union all  select '"And",your,"eyes, too, bloody","to, see",Go,"on, and, cry, in",your,coffee,"But","don''t","come, bitchin''","to, me"' from dual

)
select regexp_replace(str, '((^|").*?("|$))|,', '\1') as result
from   t 

-

+------------------------------------------------------------------------------------------------------------+
|                                                   RESULT                                                   |
+------------------------------------------------------------------------------------------------------------+
| Well,you,went,uptown,riding,in,your,limousine                                                              |
| With,your,fine,"Park Avenue clothes"                                                                       |
| You,had,the,"Dom Perignon",in,your,hand,"And the spoon",up,your,nose                                       |
| "And when you",wake,"up in the morning"                                                                    |
| "With your head on fire"                                                                                   |
| "And",your,"eyes too bloody","to see",Go,"on and cry in",your,coffee,"But","don't","come bitchin'","to me" |
+------------------------------------------------------------------------------------------------------------+

SQL Скрипка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...