2016-06-15 4 views
1

Я пытаюсь разобрать сумму в долларах из строки.Oracle REGEXP_SUBSTR Parse Dollar Суммы

Пример строки:

  • * SOC 1369.00 - NCS 1239,46 = PT LIAB 129.54
  • * СОК 1369.00 - NCS 1239,46 = PT LIAB 140
  • * SOC = 1178,00
  • * СОК 1622,00 - NCS 209,74 = 1412,26 PT LIAB РЕЦИПИЕНТ AGE
  • * ЛИНИЯ # 1 SOC 0.00 - 22.77 NCS = LIAB -22,77
  • СОК МЕТ и очистил, SOC 2062-NCS 498,56 = PT 1 ОТВЕТСТВЕННЫ 563,44
  • * SOC 1622,00 - NCS 209,74 = PT LIAB 1412 ПОЛУЧАТЕЛЬ AGE 1234

Я хочу, чтобы вытащить ответственность пациента, означающий доллар следующий текст "LIAB", "PT LIAB" или «ОТВЕТСТВЕННЫ «. Сумма в долларах может быть отрицательной и может иметь или не иметь десятичную.

Мое решение:

REPLACE(REPLACE(REGEXP_SUBSTR(REMARKS,'LIAB+[LE]?+ (-?+\d+[.]?)+\d'),'LIAB ',''),'LIABLE ','') 

Это кажется немного неуклюжим, и я полагаю, что есть более простое решение. Любые рекомендации будут оценены!

Я использую Toad для Oracle 12.8.

ответ

1

Дайте этому попытку:

SQL> with tbl(rownbr, remarks) as (
     select 1, '*SOC 1369.00 - NCS 1239.46 = PT LIAB 129.54'    from dual union 
     select 2, '*SOC 1369.00 - NCS 1239.46 = PT LIAB 140'     from dual union 
     select 3, '*SOC = 1178.00'            from dual union 
     select 4, '*SOC 1622.00 - NCS 209.74 = PT LIAB 1412.26 RECIPIENT AGE' from dual union 
     select 5, '*LINE #1 SOC 0.00 - NCS 22.77 = LIAB -22.77'    from dual union 
     select 6, 'SOC MET AND CLEARED, SOC 2062-NCS 498.56=PT LIABLE 1563.44' from dual union 
     select 7, '*SOC 1622.00 - NCS 209.74 = PT LIAB 1412 RECIPIENT AGE 1234' from dual 
     ) 
     select rownbr, 
      case 
       when remarks = regexp_replace(remarks, '.*((LIAB|LIABLE) ([-.0-9]+)).*$', '\3') then 
       '0' -- regexp_replace returns the orig string if the pattern is not found. 
       else 
       regexp_replace(remarks, '.*((LIAB|LIABLE) ([-.0-9]+)).*$', '\3') 
      end patient_liability 
     from tbl; 

    ROWNBR PATIENT_LIABILITY 
---------- ------------------------- 
     1 129.54 
     2 140 
     3 0 
     4 1412.26 
     5 -22.77 
     6 1563.44 
     7 1412 

7 rows selected. 

SQL> 
+0

Pt на сумму ответственности не является необходимым окончательное число в строке. Приношу свои извинения за то, что вы не включили пример этого в OP. Я обновлю OP. – boognish

+0

@boognish - я настраивал регулярное выражение –

+0

Приветствия! Ответ принят – boognish

0

Вы можете получить почти там с REGEXP_REPLACE() и обратной ссылкой:

REGEXP_REPLACE(REMARKS,'.*(PT LIAB|LIAB|LIABLE) (-?\d+[.]?\d+).*', '\2') 

... но передает значение без соответствующего шаблона через нетронутый (так что ваш третий пример будет по-прежнему получать *SOC = 1178.00 Вы можете использовать. выражение случай и REGEXP_LIKE(), чтобы избежать этого:

with t (remarks) as (
    select '*SOC 1369.00 - NCS 1239.46 = PT LIAB 129.54' from dual 
    union all select '*SOC 1369.00 - NCS 1239.46 = PT LIAB 140' from dual 
    union all select '*SOC = 1178.00' from dual 
    union all select '*SOC 1622.00 - NCS 209.74 = PT LIAB 1412.26 RECIPIENT AGE' from dual 
    union all select '*LINE #1 SOC 0.00 - NCS 22.77 = LIAB -22.77' from dual 
    union all select 'SOC MET AND CLEARED, SOC 2062-NCS 498.56=PT LIABLE 1563.44' from dual 
) 
SELECT REMARKS, 
    CASE WHEN REGEXP_LIKE(REMARKS, '.*(PT LIAB|LIAB|LIABLE) (-?\d+[.]?\d+).*') 
    THEN REGEXP_REPLACE(REMARKS,'.*(PT LIAB|LIAB|LIABLE) (-?\d+([.]\d+)?).*', '\2') 
    END as liability 
from t; 

REMARKS             LIABILITY 
---------------------------------------------------------- ---------- 
*SOC 1369.00 - NCS 1239.46 = PT LIAB 129.54    129.54  
*SOC 1369.00 - NCS 1239.46 = PT LIAB 140     140  
*SOC = 1178.00              
*SOC 1622.00 - NCS 209.74 = PT LIAB 1412.26 RECIPIENT AGE 1412.26 
*LINE #1 SOC 0.00 - NCS 22.77 = LIAB -22.77    -22.77  
SOC MET AND CLEARED, SOC 2062-NCS 498.56=PT LIABLE 1563.44 1563.44 

, но это не кажется, гораздо лучше, и имеющие регулярное выражение дважды делает его еще более дорогим (это, вероятно, может также все еще быть упрощена. ...). Вы можете также использовать REGEXP_REPLACE() вместо двух простых REPLACE() звонков:

REGEXP_REPLACE(
    REGEXP_SUBSTR(REMARKS, '(PT LIAB|LIAB|LIABLE) (-?\d+([.]\d+)?)'), 
    '(PT LIAB|LIAB|LIABLE) ') 

но опять же, что делает его более дорогим.

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