【问题标题】:Using regex in Oracle sql在 Oracle sql 中使用正则表达式
【发布时间】:2022-01-17 15:24:33
【问题描述】:

我想提取某个字符串的 2 部分。为此,我想使用正则表达式。 例如,字符串是:Big_Dog_0044_0080 而我的正则表达式是:Big_Dog_([0-9]+)_?([0-9A-Z]*) 第一组是 0044,第二组是 0080。

现在我的问题是将它带入一个 select 语句: 我用 regex_substr 试过了。

这是我的结果:

 select 
'Big_Dog_0044_0080' as TestString,
regexp_substr('Big_Dog_0044_0080', '([0-9]+)') Group1 , 
regexp_substr('Big_Dog_0044_0080', '([0-9A-Z]*)') Group2 from dual;

我的输出:

TESTSTRING         Group1 Group2
Big_Dog_0044_0080   0044    B

首先第 2 组是错误的,我预计 0080。 我在这里做错了什么?

第二个问题,还有其他方法可以解决这个问题吗? 我想使用 5-6 种不同的正则表达式。例如下一个将是 ([A-C])_CatWeezle

我的意思是选择输入字符串列并通过可能的正则表达式。 如果一个正则表达式匹配,则停止并提取值。

谢谢!

【问题讨论】:

    标签: sql regex oracle regexp-replace


    【解决方案1】:

    问题的第一部分很简单:

    SQL> SELECT 'Big_Dog_0044_0080' AS TestString,
      2         REGEXP_SUBSTR ('Big_Dog_0044_0080', '\d+', 1, 1) Group1,
      3         REGEXP_SUBSTR ('Big_Dog_0044_0080', '\d+', 1, 2) Group2
      4    FROM DUAL;
    
    TESTSTRING        GROU GROU
    ----------------- ---- ----
    Big_Dog_0044_0080 0044 0080
    
    SQL>
    

    我不太明白你说的 CatWeezle 是什么意思。

    【讨论】:

      【解决方案2】:

      我在这里做错了什么?

      正则表达式'([0-9A-Z]*)' 将匹配字符串中第一次出现的零个或多个数字或大写字母字符。对于您的字符串'Big_Dog_0044_0080',第一个字符是大写字母字符B,以便匹配,第二个字符i 与您的正则表达式不匹配,因此它不包含在组中。

      您声明您的字符串与模式匹配:

      Big_Dog_([0-9]+)_?([0-9A-Z]*)
      

      然后您可以使用$ 将模式锚定到字符串的末尾并可以使用:

      WITH test_data (value) AS (
        SELECT 'Big_Dog_0044_0080' FROM DUAL UNION ALL
        SELECT 'Big_Dog_00440080' FROM DUAL UNION ALL
        SELECT 'Big_Dog_00440A80' FROM DUAL
      )
      SELECT value,
             REGEXP_SUBSTR(value, '([0-9]+)_?([0-9A-Z]*)$', 1, 1, NULL, 1) AS Group1 , 
             REGEXP_SUBSTR(value, '([0-9]+)_?([0-9A-Z]*)$', 1, 1, NULL, 2) AS Group2
      FROM   test_data;
      

      哪些输出:

      VALUE GROUP1 GROUP2
      Big_Dog_0044_0080 0044 0080
      Big_Dog_00440080 00440080
      Big_Dog_00440A80 00440 A80

      (注意:第二行完全由第一组匹配,第二组宽度为零,第三行将匹配第一组,直到找到非数字字符,然后开始第二组.)

      如果分隔下划线是可选的,那么您可能需要使用固定宽度匹配(假设子字符串都是 4 个字符):

      WITH test_data (value) AS (
        SELECT 'Big_Dog_0044_0080' FROM DUAL UNION ALL
        SELECT 'Big_Dog_00440080' FROM DUAL UNION ALL
        SELECT 'Big_Dog_00440A80' FROM DUAL
      )
      SELECT value,
             REGEXP_SUBSTR(value, '([0-9]{4})_?([0-9A-Z]{4})$', 1, 1, NULL, 1) AS Group1 , 
             REGEXP_SUBSTR(value, '([0-9]{4})_?([0-9A-Z]{4})$', 1, 1, NULL, 2) AS Group2
      FROM   test_data;
      

      哪些输出:

      VALUE GROUP1 GROUP2
      Big_Dog_0044_0080 0044 0080
      Big_Dog_00440080 0044 0080
      Big_Dog_00440A80 0044 0A80

      我的意思是选择输入字符串列并检查可能的正则表达式。如果一个正则表达式匹配,则停止并提取值。

      使用CASE 表达式:

      WITH test_data (value) AS (
        SELECT 'Big_Dog_0044_0080' FROM DUAL UNION ALL
        SELECT 'Big_Dog_00440080' FROM DUAL UNION ALL
        SELECT 'Big_Dog_00440A80' FROM DUAL UNION ALL
        SELECT 'A_CatWeezle' FROM DUAL
      )
      SELECT value,
             CASE
             WHEN REGEXP_LIKE(value, '^Big_Dog_(\d{4})_?([0-9A-Z]{4})$')
             THEN REGEXP_SUBSTR(value, '^Big_Dog_(\d{4})_?([0-9A-Z]{4})$', 1, 1, NULL, 1)
             WHEN REGEXP_LIKE(value, '^([A-C])_CatWeezle$')
             THEN REGEXP_SUBSTR(value, '^([A-C])_CatWeezle$', 1, 1, NULL, 1)
             END AS group1,
             CASE
             WHEN REGEXP_LIKE(value, '^Big_Dog_(\d{4})_?([0-9A-Z]{4})$')
             THEN REGEXP_SUBSTR(value, '^Big_Dog_(\d{4})_?([0-9A-Z]{4})$', 1, 1, NULL, 2)
             END AS group2
      FROM   test_data;
      

      输出:

      VALUE GROUP1 GROUP2
      Big_Dog_0044_0080 0044 0080
      Big_Dog_00440080 0044 0080
      Big_Dog_00440A80 0044 0A80
      A_CatWeezle A

      db小提琴here

      【讨论】:

      • 非常感谢!这正是我想要的。
      猜你喜欢
      • 2021-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-20
      • 2019-06-10
      • 1970-01-01
      • 1970-01-01
      • 2020-03-23
      相关资源
      最近更新 更多