Oracle正则表达式从上次出现时拆分字符串

ajm*_*d04 0 regex sql oracle oracle11g

我仍在学习oracle中的regexp我被困在中间,下面是我的示例代码:

with t(val)
as
(
  --format: xyz_year_month_date
  select 'my_new_table_2015_06_31' from dual
  union all
  select 'my_new_table_temp_2016_06_31' from dual
 )
 select reverse(regexp_substr(reverse(val),'[^_]+',1,4)) col4,
 reverse(regexp_substr(reverse(val),'[^_]+',1,3)) col3,
 reverse(regexp_substr(reverse(val),'[^_]+',1,2)) col2,
 reverse(regexp_substr(reverse(val),'[^_]+',1,1)) col1
 from t;

Output:
COL4 COL3 COL2 COL1
table 2015 06 31
temp 2016 06 31

Expected output:
COL4 COL3 COL2 COL1
my_new_table 2015 06 31
my_new_table_temp 2016 06 31
Run Code Online (Sandbox Code Playgroud)

提前致谢.

MT0*_*MT0 5

你可以通过提取不同的捕获组(用()圆括号括起来)来实现它而不需要双向反转:

WITH t ( VAL ) AS (
  SELECT 'my_new_table_2015_06_31' FROM DUAL UNION ALL
  SELECT 'my_new_table_temp_2016_06_31' FROM DUAL
)
SELECT REGEXP_SUBSTR( val, '^(.*)_([^_]+)_([^_]+)_([^_]+)$', 1, 1, NULL, 1 ) AS COL4,
       REGEXP_SUBSTR( val, '^(.*)_([^_]+)_([^_]+)_([^_]+)$', 1, 1, NULL, 2 ) AS COL3,
       REGEXP_SUBSTR( val, '^(.*)_([^_]+)_([^_]+)_([^_]+)$', 1, 1, NULL, 3 ) AS COL2,
       REGEXP_SUBSTR( val, '^(.*)_([^_]+)_([^_]+)_([^_]+)$', 1, 1, NULL, 4 ) AS COL1
FROM   t
Run Code Online (Sandbox Code Playgroud)

您甚至可以通过使用以下方法使正则表达式更简单:

'^(.+)_(.+)_(.+)_(.+)$'
Run Code Online (Sandbox Code Playgroud)

第一个.+是贪婪的,所以它会尽可能地匹配,直到只有足够的字符串留给第2到第4个捕获组的最小匹配.

但是,您不需要正则表达式:

WITH t ( VAL ) AS (
  SELECT 'my_new_table_2015_06_31' FROM DUAL UNION ALL
  SELECT 'my_new_table_temp_2016_06_31' FROM DUAL
)
SELECT SUBSTR( val, 1,        pos1 - 1        ) AS col4,
       SUBSTR( val, pos1 + 1, pos2 - pos1 - 1 ) AS col3,
       SUBSTR( val, pos2 + 1, pos3 - pos2 - 1 ) AS col2,
       SUBSTR( val, pos3 + 1                  ) AS col1
FROM   (
  SELECT val,
         INSTR( val, '_', -1, 1 ) AS pos3,
         INSTR( val, '_', -1, 2 ) AS pos2,
         INSTR( val, '_', -1, 3 ) AS pos1
  FROM   t
);
Run Code Online (Sandbox Code Playgroud)