您几乎可以通过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) ')
但这又让它变得更贵了。