首页 > 解决方案 > Oracle SQL 如何使用正则表达式构建字符串?

问题描述

使用 Oracle SQL,如何从较大的列字符串创建新字符串?

例如说我们有:

example-dev5-ex1-ex2

作为列。我想把它变成:

example-dev5.ex0.ex1.ex2.

ex0 是我需要带入字符串的硬编码值。开发环境也可以是 dev10、dev11 等。所以 dev 末尾的另一个数字。

我是一个完整的正则表达式新手,无法理解它,所以任何帮助和解释它如何解决这个问题将不胜感激。

标签: sqlregexoracle

解决方案


如果您只想替换-ex??后缀,以便始终添加连续的.ex0....ex??后缀,请使用正则表达式:

^([^-]*-[^-]*).*-ex(\d+)$

为了匹配字符串的开头,^前两个连字符分隔的术语([^-]*-[^-]*)然后读取其余字符.*,直到-ex(\d+)字符串末尾的最后一个术语$

然后,您可以在递归子查询因式分解子句中使用前两个术语和最后一个术语来生成连续的后缀,直到达到正确的深度:

甲骨文设置

CREATE TABLE test_data( value ) AS
  SELECT 'example-dev5-ex1-ex2'   FROM DUAL UNION ALL
  SELECT 'example1-dev10-ex3'     FROM DUAL UNION ALL
  SELECT 'example2-dev99-ex2-ex7' FROM DUAL;

查询

WITH rsqfc ( value, max_depth, depth ) AS (
  SELECT REGEXP_SUBSTR( value, '^([^-]*-[^-]*).*-ex(\d+)$', 1, 1, NULL, 1 ) || '.ex0',
         TO_NUMBER( REGEXP_SUBSTR( value, '^([^-]*-[^-]*).*-ex(\d+)$', 1, 1, NULL, 2 ) ),
         0
  FROM test_data
UNION ALL
  SELECT value || '.ex' || (depth+1),
         max_depth,
         depth + 1
  FROM   rsqfc
  WHERE  depth < max_depth
)
SELECT value
FROM   rsqfc
WHERE  depth = max_depth;

输出

| 价值 |
| :------------------------------------------------------------ |
| 示例-dev5.ex0.ex1.ex2 |
| 示例1-dev10.ex0.ex1.ex2.ex3 |
| 示例2-dev99.ex0.ex1.ex2.ex3.ex4.ex5.ex6.ex7 |

db<>在这里摆弄


如果您只想添加并将后缀.ex0更改为在开头有 a ,那么您可以使用:-ex??.

甲骨文查询

SELECT REGEXP_SUBSTR( value, '^[^-]*-[^-]*' ) || '.ex0' || REPLACE( REGEXP_SUBSTR( value, '(-ex\d+)+$' ), '-', '.' ) AS value
FROM   test_data

输出

| 价值 |
| :------------------------- |
| 示例-dev5.ex0.ex1.ex2 |
| 示例1-dev10.ex0.ex3 |
| 示例2-dev99.ex0.ex2.ex7 |

db<>在这里摆弄


推荐阅读