Oracle Regex从字符串中的键值对中获取值

时间:2018-05-09 16:52:44

标签: sql regex oracle regexp-replace

考虑以下列行:

col
-------------------------
'{"day":"8","every":"2"}'

我试图通过正则表达式从这个字符串中得到8来计算出这一天。

到目前为止,我有:

SELECT 
    regexp_replace(col, '{"day":[^0-9]', '') as "day"
FROM 
   mytable;

这给了我:

 day
 ---------------
 8","every":"2"}

我无法弄清楚如何从前面的第一个数字中过滤出其余的字符串。在我的例子中,我只想要这一行的数字8。

3 个答案:

答案 0 :(得分:3)

如果您有幸使用Oracle 12c,请查看JSON_VALUE

WITH t (s)
AS (
    SELECT '{"day":"8","every":"2"}'
    FROM DUAL
    )
SELECT JSON_VALUE(s, '$.day'  ) AS day
    ,  JSON_VALUE(s, '$.every') AS every
FROM t;

DAY   EVERY
---   -----
8     2

答案 1 :(得分:1)

这个怎么样?

SELECT 
    regexp_replace(col, '{"day":"([0-9]+).*', '\1') as "day"
FROM 
   mytable;

答案 2 :(得分:1)

如果您无法访问JSON_VALUE(),那么除非您始终知道JSON字符串中day键的位置,否则我建议使用以下正则表达式:

SELECT REGEXP_REPLACE(col, '^.*"day":"(\d+)".*$', '\1') AS day
  FROM mytable;

这会将整个字符串(假设它匹配!)替换为第一个捕获组的内容(括在括号中:(\d+))。 \d表示数字0-9。如果您还想返回NULL值,可以将\d+替换为\d*。如果可能是负数或非数字值,那么我建议如下:

SELECT REGEXP_REPLACE(col, '^.*"day":"[^"]*".*$', '\1') AS day
  FROM mytable;

这将返回day键中可能包含的任何字符。

仅供参考,一旦您拥有值,数字或非数字,您可以使用TO_NUMBER()REGEXP_SUBSTR()安全地将其转换为数字:

SELECT COALESCE( TO_NUMBER( REGEXP_SUBSTR( REGEXP_REPLACE( col, '^.*"day":"[^"]*".*$', '\1' ), '\d+' ) ), 0 ) AS day
  FROM mytable;

希望这有帮助。