Запрос Oracle Regexp_Substr или Regexp_Replace, не удовлетворяющий все случаи - PullRequest
1 голос
/ 06 марта 2019

Я в Oracle 12c R1. Я хочу извлечь первые две части строки и последнюю, которая имеет X

  Input : 'AB12,AB23,AB50,AB71X,AB43,AB98X,AB11'
    Expected Output :  AB12,AB23,AB98

Пробовал ниже,

  SELECT REGEXP_REPLACE('AB12,AB23,AB50,AB71X,AB43,AB98X,AB11','(.{9}).*(,.{4})X(.+$)?','\1\2) col1 FROM dual;

Ноне удалось правильно получить часть X для строки ниже

  'AB12X,AB23X,AB50X,AB71,AB43'   Expected Output => AB12,AB23,AB50
                                  Output => AB12X,AB2,AB50

  'AB12,AB23X'                    Expected Output => AB12,AB23
                                  Output => AB12,AB23X

Ответы [ 3 ]

2 голосов
/ 06 марта 2019

Нет необходимости в регулярных выражениях.Вы можете использовать instr с th_appearance = -1, чтобы начать с конца

  with t as (select 'AB12,AB23,AB50,AB71X,AB43,AB98X,AB11' as input from dual)
  select 
  substr(input,1, instr(input,',', 1)-1) as firstPart,
  substr(input,instr(input,',', 1)+1, instr(input,',', 1, 1)-1) as secondPart,
  substr(substr(input,1, instr(input,'X,', -1)-1), instr(substr(input,1, instr(input,'X,', -1)), ',', -1)+1) as thirdPart
  from t;

Возвращает:

 AB12   AB23    AB98

Или объединено:

 with t as (select 'AB12,AB23,AB50,AB71X,AB43,AB98X,AB11' as input from dual)
  select 
  substr(input,1, instr(input,',', 1)-1) || ',' ||
  substr(input,instr(input,',', 1)+1, instr(input,',', 1, 1)-1)  || ',' ||
  substr(substr(input,1, instr(input,'X,', -1)-1), instr(substr(input,1, instr(input,'X,', -1)), ',', -1)+1) as output
  from t;

Возвращает:

AB12,AB23,AB98
1 голос
/ 06 марта 2019

Этот запрос может помочь:

select listagg(c1, ',') within group (order by null) from
 (select c1, lvl, rn, max(rn) over (partition by null) rn2 from 
   (select c1, lvl, case when c1 like '%X' then rownum end rn from 
      (select regexp_substr('AB12,AB23,AB50,AB71X,AB43,AB98X,AB11','[^,]+', 1, level) c1, level lvl from dual
      connect by regexp_substr('AB12,AB23,AB50,AB71X,AB43,AB98X,AB11', '[^,]+', 1, level) is not null)
    ) t
  )
where lvl in (1,2)
   or rn2 = rn
order by lvl asc;
0 голосов
/ 07 марта 2019

Попробуйте:

select regexp_replace('AB12,AB23,AB50,AB71X,AB43,AB98X,AB11', '^(.{4},.{4}),.*,(.{4})X.*$', '\1,\2')
from dual;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...