【问题标题】:Oracle Regex grabbing value from key value pair in a stringOracle Regex 从字符串中的键值对中获取值
【发布时间】:2018-10-19 20:55:18
【问题描述】:

考虑以下列行:

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

我正在尝试使用正则表达式从该字符串中获取 8 来计算日期。

到目前为止我有:

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

这给了我:

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

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

【问题讨论】:

  • 我使用的是 11g。
  • 正则表达式 ^{"day":"(\d+).*}$ 替换为 \1
  • 完美。这样可行。你能解释一下 \1 是做什么的吗?
  • () 字符捕获数字,\1 表示“给我第一个捕获组”(在这种情况下是唯一一个)。
  • 太棒了。谢谢你们!

标签: sql regex oracle regexp-replace


【解决方案1】:

如果您有幸使用 Oracle 12c 第 1 版 (12.1.0.2) 或更高版本,请查看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

【讨论】:

    【解决方案2】:

    这个怎么样?

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

    【讨论】:

    • 只返回 "
    • @eddiem [^0-9] 认为这不包括数字
    • 对不起,我的第一个答案完全错误,但我认为这个应该可以。
    【解决方案3】:

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

    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;
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-25
      • 2020-01-04
      相关资源
      最近更新 更多