【问题标题】:Regex - extracting numbers from string in Oracle SQL [closed]正则表达式 - 从 Oracle SQL 中的字符串中提取数字 [关闭]
【发布时间】:2018-11-28 11:19:46
【问题描述】:

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

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

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

【问题讨论】:

  • 你期待什么结果?

标签: sql oracle plsql


【解决方案1】:

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

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

【讨论】:

  • 感谢您的回答...如果我想创建 SQL,则将字符串分为 3 部分。(SQL 返回 3 列)例如对于 [ 1d (8h; 24h; 48.5h; 72h; 96h)] x (1 to 5) 它将是:column1 = 1, column2 = 8;24;48.5;72;96, column 3 = 1;5。如何做到这一点?
  • @Cugar 更新了——你最好把你的要求放到你的问题中,这样当你问问题时每个人都知道你在做什么,而不是得到答案然后说“实际上,我想要别的东西"。
  • 感谢@MT0 的回答和帮助。
【解决方案2】:

您可以通过 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|

【讨论】:

  • 您的意思是将 48.5 视为两个单独的数字吗?
  • @AlexPoole 哦,谢谢 Alex,已使用“.\”修复
  • 嗯,只包含句号即可解决;反斜杠在做什么? (还必须希望字符串中不会有任何其他句点,不是小数分隔符!)
猜你喜欢
  • 2014-03-04
  • 2013-07-31
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 2014-06-02
  • 2014-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多