1

我正在尝试从字符串中解析美元金额。

示例字符串:

  • *SOC 1369.00 - NCS 1239.46 = PT LIAB 129.54
  • *SOC 1369.00 - NCS 1239.46 = PT LIAB 140
  • *SOC = 1178.00
  • *SOC 1622.00 - NCS 209.74 = PT LIAB 1412.26 接受者年龄
  • *线#1 SOC 0.00 - NCS 22.77 = LIAB -22.77
  • SOC 符合并清除,SOC 2062-NCS 498.56=PT LIABLE 1563.44
  • *SOC 1622.00 - NCS 209.74 = PT LIAB 1412 接受者年龄 1234

我想提取患者责任,即文本“LIAB”、“PT LIAB”或“LIABLE”后面的美元金额。美元金额可以是负数,可能有也可能没有小数。

我的解决方案:

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

这似乎有点笨拙,我认为有一个更简单的解决方案。任何指导将不胜感激!

我正在使用 Toad for Oracle 12.8。

4

2 回答 2

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>
于 2016-06-15T18:02:43.520 回答
0

您几乎可以REGEXP_REPLACE()通过反向参考到达那里:

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

...但是通过 untouched 传递一个没有匹配模式的值(所以你的第三个例子仍然会得到*SOC = 1178.00. 你可以使用 case 表达式并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) ')

但这又使它变得更加昂贵。

于 2016-06-15T17:39:18.540 回答