微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用正则表达式提取逗号后的值

如何解决使用正则表达式提取逗号后的值

我使用的是 Oracle 19c 数据库

下面是我的字符串值

variable B1 varchar2(60)
exec :B1:='(199,''TEST121''),(156,''TEST''),(1561,''TEST99'')';

我希望输出

|    ID    |     NAME       |
| -------- | -------------- |
|       199|   TEST121      |
|       156|   TEST         |
|      1561|   TEST99       |
select  regexp_substr(regexp_substr(:b1,'[^A-Z+0-9][0-9]+',1,level),'[0-9]+') as id,regexp_substr(:b1,'[A-Z]+[0-9]',level) as name from dual connect by regexp_substr(:b1,'[0-9]',level) is not null;

查询仅提供以数字结尾的字符串值的输出

解决方法

这是一种选择:

SQL> WITH
  2     test (col)
  3     AS
  4        (SELECT '(199,''TEST121''),(156,''TEST''),(1561,''TEST99'')' FROM DUAL)
  5  SELECT SUBSTR (str,1,INSTR (str,',') - 1) id,6         SUBSTR (str,') + 1) name
  7    FROM (    SELECT REGEXP_SUBSTR (
  8                        REPLACE (
  9                           REPLACE (
 10                              REPLACE (REPLACE (col,'),(','#'),CHR (39),''),11                              '(',12                              ''),13                           ')',14                           ''),15                        '[^#]+',16                        1,17                        LEVEL) str
 18                FROM test
 19          CONNECT BY LEVEL <= REGEXP_COUNT (REPLACE (col,'#') + 1);

ID                               NAME
-------------------------------- --------------------------------
199                              TEST121
156                              TEST
1561                             TEST99

SQL>

它有什么作用?

  • 第 1 - 4 行 - 示例数据
  • 行 #8 - 14 - 将 ),( 替换为 #(以获得更简单的分隔符);删除前导和尾随括号
  • 第 7 - 19 行 - 将示例字符串拆分成行
  • 第 5、6 行 - 从每行中提取 IDNAME
,

@Littlefoot 给出的选项的详细解释

下面是将多值字符串转换为列和行的测试用例。

    set lines 999 pages 999
    col ID for a20
    col NAME for a20
    
    variable B1 varchar2(60)
    exec :B1:='(99,''TABLE1''),(56,''INDEX1''),(199,''TABLE''),''INDEX'')';
    variable B1 varchar2(100)
    exec :B1:='(''TABL234E1~'',99),(''I1NDEX1~'',5ABC6),(''TAB1LE'',4ABC0),(''IND11EX'',6ACDE0)';
    
    WITH
       test (col)
       AS
          (SELECT :b1 FROM DUAL)
    SELECT SUBSTR (str,SUBSTR (str,') + 1) name
      FROM (    SELECT REGEXP_SUBSTR (
                          REPLACE (
                             REPLACE (
                                REPLACE (REPLACE (col,'(',')','[^#]+',LEVEL) str
                  FROM test
            CONNECT BY LEVEL <= REGEXP_COUNT (REPLACE (col,'#') + 1);

说明:

    variable B1 varchar2(60)
    
    exec :B1:='(99,''INDEX'')';

步骤 1

    WITH
      test (col)
      AS
         (SELECT :b1 FROM DUAL)
      select col from test;

此步骤有助于获取 oracle 行格式的基本字符串。

结果:

     (99,'TABLE1'),'INDEX1'),'TABLE'),'INDEX')

第2步

    WITH
      test (col)
      AS
         (SELECT :b1 FROM DUAL)
      select REPLACE(col,'#') from test;

此步骤有助于将 '),(' 替换为 '#'(以获得更简单的多值字符串分隔符)。

结果:

    (99,'TABLE1'#56,'INDEX1'#199,'TABLE'#156,'INDEX')

步骤 3

    WITH
      test (col)
      AS
         (SELECT :b1 FROM DUAL)
      select REPLACE(REPLACE(col,CHR(39),'') from test;

此步骤有助于替换上一步中的单引号。

结果:

    (TABL234E1~,99#I1NDEX1~,5ABC6#TAB1LE,4ABC0#IND11EX,6ACDE0)

第 4 步

    WITH
      test (col)
      AS
         (SELECT :b1 FROM DUAL)
      select REPLACE(REPLACE(REPLACE(col,'') from test;

此步骤有助于将 '(' 替换为 ''(删除前一步中的前导括号)。

结果:

    99,TABLE1#56,INDEX1#199,TABLE#156,INDEX)

第5步

    WITH
      test (col)
      AS
         (SELECT :b1 FROM DUAL)
      select REPLACE(REPLACE(REPLACE(REPLACE(col,'') from test;

此步骤有助于将 ')' 替换为 ''(删除前一步中的尾括号)。

结果:

   99,INDEX

第 6 步

    WITH
       test (col)
       AS
          (SELECT :b1 FROM DUAL)
    SELECT *
      FROM (    SELECT REGEXP_SUBSTR (
                          REPLACE (
                             REPLACE (
                                REPLACE (REPLACE (col,'#') + 1);

这一步有两个组成部分:

    a. REGEXP_SUBSTR(<value from previous step>,LEVEL)
    '[^#]+' ==> searches and gets every character other than '#' 
    1==> starting position of the searches
    LEVEL==> LEVEL can be used in conjunction with CONNECT BY LEVEL clause. All the chunks of the source string can be displayed by using the LEVEL keyword as the match occurrence. 

    b. CONNECT BY LEVEL <= REGEXP_COUNT (REPLACE (col,'#') + 1
    REPLACE (col,'#') ==> This helps in replacing '),(' with '#' (to get a simpler separator for multivalued string).
    REGEXP_COUNT(<output from previous step>,'#')+1==> Count the number of '#' +1 in the source string. 
    Here,the CONNECT BY LEVEL clause generates the rows equal to the number of '#' +1 in the source string. 

结果:

    99,TABLE1
    56,INDEX1
    199,TABLE
    156,INDEX

第7步

    WITH
       test (col)
       AS
          (SELECT :b1 FROM DUAL)
    SELECT SUBSTR (str,'#') + 1);
    

这一步有两个组成部分: a.SUBSTR (str,') - 1)==> str 来自前面的输出,从第一个位置开始,它将字符从 ',' 到 -1 位置。 b.SUBSTR (str,') + 1) name==> str 来自前面的输出并从 ',' 开始,它将字符从 ',' 搜索到 +1 位置。

结果:

    ID                   NAME
    -------------------- --------------------
    99                   TABLE1
    56                   INDEX1
    199                  TABLE
    156                  INDEX

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?