简体   繁体   English

Oracle SQL regexp_substr

[英]Oracle SQL regexp_substr

I have a query which fetches value matching the pattern, I want it to fetch all prefvalue instead of only CEROTG我有一个查询,它获取与模式匹配的值,我希望它获取所有 prefvalue 而不是只获取 CEROTG

SELECT regexp_substr('prefvalue:CEROTG-2 prefvalue:CEROTG prefvalue:CEROTG_1', 'prefvalue:([[:alnum:]_]+)') as Result from dual

Current Output电流输出

prefvalue:CEROTG

Expected Output预期产出

prefvalue:CEROTG
prefvalue:CEROTG-2
prefvalue:CEROTG_1

One option uses a recursive query:一种选择使用递归查询:

with 
    data as (select 'prefvalue:CEROTG-2 prefvalue:CEROTG prefvalue:CEROTG_1' str from dual),
    cte(str, res, lvl) as (
        select str, regexp_substr(str, 'prefvalue:([[:alnum:]_-]+)'), 1 lvl from data
        union all
        select str, regexp_substr(str, 'prefvalue:([[:alnum:]_-]+)', 1, lvl + 1), lvl + 1 
        from cte 
        where lvl < regexp_count(str, 'prefvalue:([[:alnum:]_-]+)')
    )
select res from cte

Demo on DB Fiddle : DB Fiddle 上的演示

| RES                |
| :----------------- |
| prefvalue:CEROTG-2 |
| prefvalue:CEROTG   |
| prefvalue:CEROTG_1 |

You can use simple string functions in a recursive subquery-factoring clause:您可以在递归子查询分解子句中使用简单的字符串函数:

WITH rsqfc ( entry_data, start_pos, end_pos ) AS (
  SELECT entry_data, 1, INSTR( entry_data, ' ', 1 )
  FROM   prefdir_entrydata
UNION ALL
  SELECT entry_data, end_pos + 1, INSTR( entry_data, ' ', end_pos + 1 )
  FROM   rsqfc
  WHERE  end_pos > 0
)
SELECT CASE end_pos
       WHEN 0
       THEN SUBSTR( entry_data, start_pos )
       ELSE SUBSTR( entry_data, start_pos, end_pos - start_pos )
       END AS value
FROM   rsqfc

Which, for your sample data:其中,对于您的示例数据:

CREATE TABLE prefdir_entrydata ( entry_data ) AS
SELECT 'prefvalue:CEROTG-2 prefvalue:CEROTG prefvalue:CEROTG_1' FROM DUAL;

Outputs:输出:

\n| | VALUE |价值 |\n| | :----------------- | :----------------- |\n| | prefvalue:CEROTG-2 |优先值:CEROTG-2 |\n| | prefvalue:CEROTG |优先值:CEROTG |\n| | prefvalue:CEROTG_1 |优先值:CEROTG_1 |\n

db<>fiddle here db<> 在这里摆弄


An example that handles multiple input rows is:处理多个输入行的示例是:

WITH rsqfc ( id, entry_data, start_pos, end_pos ) AS (
  SELECT id, entry_data, 1, INSTR( entry_data, ' ', 1 )
  FROM   prefdir_entrydata
  WHERE  dist_name_short = 'prefentry=imagerepository,prefgroup=cdi_globals,prefgroup=component,prefgroup=system,prefcontext=default,prefroot=prefroot'
UNION ALL
  SELECT id, entry_data, end_pos + 1, INSTR( entry_data, ' ', end_pos + 1 )
  FROM   rsqfc
  WHERE  end_pos > 0
)
SELECT id,
       CASE end_pos
       WHEN 0
       THEN SUBSTR( entry_data, start_pos )
       ELSE SUBSTR( entry_data, start_pos, end_pos - start_pos )
       END AS value
FROM   rsqfc
ORDER BY id, start_pos

Which, for the test data:其中,对于测试数据:

CREATE TABLE prefdir_entrydata ( id, entry_data, dist_name_short ) AS
SELECT 1,
       'prefvalue:CEROTG-2 prefvalue:CEROTG prefvalue:CEROTG_1',
       'prefentry=imagerepository,prefgroup=cdi_globals,prefgroup=component,prefgroup=system,prefcontext=default,prefroot=prefroot'
FROM   DUAL UNION ALL
SELECT 2,
       'prefvalue:CEROTG-2a prefvalue:CEROTG_1v2',
       'prefentry=imagerepository,prefgroup=cdi_globals,prefgroup=component,prefgroup=system,prefcontext=default,prefroot=prefroot'
FROM   DUAL;

Outputs:输出:

\nID |身份证 | VALUE价值               \n-: | -: | :------------------- :--------------------\n 1 | 1 | prefvalue:CEROTG-2优先值:CEROTG-2  \n 1 | 1 | prefvalue:CEROTG优先值:CEROTG    \n 1 | 1 | prefvalue:CEROTG_1优先值:CEROTG_1  \n 2 | 2 | prefvalue:CEROTG-2a优先值:CEROTG-2a \n 2 | 2 | prefvalue:CEROTG_1v2优先值:CEROTG_1v2\n

db<>fiddle here db<> 在这里摆弄

WITH tbl(DATA) AS (
  SELECT 'prefvalue:CEROTG-2 prefvalue:CEROTG prefvalue:CEROTG_1'
  FROM dual
)
SELECT REGEXP_SUBSTR(DATA, '(.*?)( |$)', 1, LEVEL, NULL, 1) ELEMENT
FROM tbl
CONNECT BY LEVEL <= REGEXP_COUNT(DATA, ' ')+1; 

ELEMENT                                               
------------------------------------------------------
prefvalue:CEROTG-2                                    
prefvalue:CEROTG                                      
prefvalue:CEROTG_1                                    

3 rows selected.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM