正则表达式-从Oracle SQL中的字符串中提取数字

时间:2018-06-19 13:08:59

标签: sql oracle plsql

如何使用SQL或PL / SQL从字符串下面提取所有数字?

[6d(1.5h; 31h)] x(5至7)

[1d(8h; 24h; 48.5h; 72h; 96h)] x(1至5)

2 个答案:

答案 0 :(得分:2)

您可以使用正则表达式和相关的层次结构查询来获取值:

Oracle设置

CREATE TABLE table_name ( id, value ) AS
SELECT 1, '[ 6d (1.5h; 31h)] x (5 to 7)' FROM DUAL UNION ALL
SELECT 2, '[ 1d (8h; 24h; 48.5h; 72h; 96h)] x (1 to 5)' FROM DUAL;

查询

SELECT id, COLUMN_VALUE
FROM   table_name t
       CROSS JOIN
       TABLE(
         CAST(
           MULTISET(
             SELECT REGEXP_SUBSTR( t.value, '\d+\.?\d*', 1, LEVEL )
             FROM   DUAL
             CONNECT BY LEVEL <= REGEXP_COUNT( t.value, '\d+\.?\d*' )
           ) AS SYS.ODCINUMBERLIST
         )
       ) n;

结果

ID  COLUMN_VALUE
--- ------------
1   6
1   1.5
1   31
1   5
1   7
2   1
2   8
2   24
2   48.5
2   72
2   96
2   1
2   5

查询2

SELECT REGEXP_SUBSTR( value, '\[\s*([0-9.]+)d\s*\((.*?)\)\]\s*x\s*\(([0-9.]+)\s*to\s*([0-9.]+)\)', 1, 1, NULL, 1 ) AS days,
       REGEXP_REPLACE(
         REGEXP_SUBSTR( value, '\[\s*([0-9.]+)d\s*\((.*?)\)\]\s*x\s*\(([0-9.]+)\s*to\s*([0-9.]+)\)', 1, 1, NULL, 2 ),
         '[^0-9.;]'
       )AS hours,
       REGEXP_SUBSTR( value, '\[\s*([0-9.]+)d\s*\((.*?)\)\]\s*x\s*\(([0-9.]+)\s*to\s*([0-9.]+)\)', 1, 1, NULL, 3 ) AS x_from,
       REGEXP_SUBSTR( value, '\[\s*([0-9.]+)d\s*\((.*?)\)\]\s*x\s*\(([0-9.]+)\s*to\s*([0-9.]+)\)', 1, 1, NULL, 4 ) AS x_to
FROM   table_name t;

结果

DAYS HOURS           X_FROM X_TO
---- --------------- ------ ----
   6          1.5;31      5    7
   1 8;24;48.5;72;96      1    5

答案 1 :(得分:1)

您可以通过 regexp_replace 的作用来导出由定界符(在本例中为竖线)分隔的所有数字,如下所示:

select regexp_replace('[ 6d (1.5h; 31h)] x (5 to 7)','[^0-9.]+','|') str from dual union all
select regexp_replace('[ 1d (8h; 24h; 48.5h; 72h; 96h)] x (1 to 5)','[^0-9.]+','|') from dual;

STR
------------------
|6|1.5|31|5|7|
|1|8|24|48.5|72|96|1|5|