oracle 通过regexp_substr捕获Q和X之间的字符串

eqoofvh9  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(147)

我想使用REGEXP_SUBSTR在Oracle中捕获两个特定字符串之间的字符串,它在regex101中工作,但当我在Oracle中使用它时,它不工作。有人能帮忙吗?
Pattern: ^Q-.*[\S\s]*?^X-.*

Data:
A-bbbbbb;cccccc;ggggggg
Addrffjfjfjffj
Fjfjfjf
B-rjfjfjffjfj;fjfjffj;tkgkfck
Q-fjfjfjfj;fkfkffkj;gkfkfk
Djfjfjjfjffjfjfj
Fjfjfjfjf
X-fjfjfjf;fjfnfjf;af
Z-fjfjfjfjfjfjfj;gkgjfjcnf;gkgjgk

https://regex101.com/r/Df9RU6/1

Result/Captured: 
Q-fjfjfjfj;fkfkffkj;gkfkfk
Djfjfjjfjffjfjfj
Fjfjfjfjf
X-fjfjfjf;fjfnfjf;af
wi3ka0sx

wi3ka0sx1#

  • 不要使用regex 101测试Oracle正则表达式;它不使用相同的正则表达式语法,因此您无法确定查询是否有效。*

Oracle不支持在字符列表(如[\s\S])中使用类似Perl的表达式。如果你想使用类似的东西,那么使用POSIX字符类:

([[:space:]]|[^[:space:]])

然而,你似乎想要的是:

SELECT REGEXP_SUBSTR(
         value,
         '(^|' || CHR(10) || ')(Q-(' || CHR(10) || '|.)*?' || CHR(10) || 'X-.*)',
         1,
         1,
         NULL,
         2
       ) AS match
FROM   table_name;

其中,对于样本数据:

CREATE TABLE table_name (value) AS
SELECT 'A-bbbbbb;cccccc;ggggggg
Addrffjfjfjffj
Fjfjfjf
B-rjfjfjffjfj;fjfjffj;tkgkfck
Q-fjfjfjfj;fkfkffkj;gkfkfk
Djfjfjjfjffjfjfj
Fjfjfjfjf
X-fjfjfjf;fjfnfjf;af
Z-fjfjfjfjfjfjfj;gkgjfjcnf;gkgjgk' FROM DUAL;

输出:
| 匹配|
| --|
| Q-fjfjfjfj;fkfkffkj; Gkfkfk杰菲菲菲X-fjfjfjf;fjfnfjf; af|
但是,正则表达式很慢。即使它更多的是类型,使用简单的字符串函数可能会更高效:

SELECT SUBSTR(
         value,
         spos + 1,
         CASE
         WHEN INSTR(value, CHR(10), epos + 1) > 0
         THEN INSTR(value, CHR(10), epos + 1)
         ELSE LENGTH(value) + 1
         END - spos - 1
       ) AS match
FROM   (
  SELECT CHR(10) || value AS value,
         INSTR(CHR(10) || value, CHR(10) || 'Q-') AS spos,
         INSTR(
           CHR(10) || value,
           CHR(10) || 'X-',
           INSTR(CHR(10) || value, CHR(10) || 'Q-')
         ) AS epos
  FROM   table_name
)
WHERE  epos > 0;

也有相同的输出。
如果你想为每一行得到多个结果,那么使用递归查询:

WITH rsqfc (id, value, occurrence, max_occurrences) AS (
  SELECT id,
         value,
         1, 
         REGEXP_COUNT(
           value,
           '(^|' || CHR(10) || ')(Q-(' || CHR(10) || '|.)*?' || CHR(10) || 'X-.*)'
         )
  FROM   table_name
UNION ALL
  SELECT id, value, occurrence + 1, max_occurrences
  FROM   rsqfc
  WHERE  occurrence < max_occurrences
)
SELECT id,
       REGEXP_SUBSTR(
         value,
         '(^|' || CHR(10) || ')(Q-(' || CHR(10) || '|.)*?' || CHR(10) || 'X-.*)',
         1,
         occurrence,
         NULL,
         2
       ) AS match
FROM   rsqfc;

或者,使用简单(更快)的字符串函数:

WITH rsqfc (id, value, qpos, xpos) AS (
  SELECT id,
         CHR(10) || value,
         INSTR(CHR(10) || value, CHR(10) || 'Q-'),
         CASE INSTR(CHR(10) || value, CHR(10) || 'Q-')
         WHEN 0
         THEN 0
         ELSE INSTR(
                CHR(10) || value,
                CHR(10) || 'X-',
                INSTR(CHR(10) || value, CHR(10) || 'Q-')
              )
         END
  FROM   table_name
UNION ALL
  SELECT id,
         value,
         INSTR(value, CHR(10) || 'Q-', xpos + 1),
         CASE INSTR(value, CHR(10) || 'Q-', xpos + 1)
         WHEN 0
         THEN 0
         ELSE INSTR(
                value,
                CHR(10) || 'X-',
                INSTR(CHR(10) || value, CHR(10) || 'Q-', xpos + 1)
              )
         END
  FROM   rsqfc
  WHERE  xpos > 0
)
SELECT id,
       SUBSTR(
         value,
         qpos + 1,
         CASE
         WHEN INSTR(value, CHR(10), xpos + 1) > 0
         THEN INSTR(value, CHR(10), xpos + 1)
         ELSE LENGTH(value) + 1
         END - qpos - 1
       ) AS match
FROM   rsqfc
WHERE  xpos > 0;

其中,对于样本数据:

CREATE TABLE table_name (id, value) AS
SELECT 1, 'A-bbbbbb;cccccc;ggggggg
Addrffjfjfjffj
Fjfjfjf
B-rjfjfjffjfj;fjfjffj;tkgkfck
Q-fjfjfjfj;fkfkffkj;gkfkfk
Djfjfjjfjffjfjfj
Fjfjfjfjf
X-fjfjfjf;fjfnfjf;af
Z-fjfjfjfjfjfjfj;gkgjfjcnf;gkgjgk' FROM DUAL UNION ALL
SELECT 2, 'A-bbbbbb;cccccc;ggggggg
Addrffjfjfjffj
Fjfjfjf
B-rjfjfjffjfj;fjfjffj;tkgkfck
Q-fjfjfjfj;fkfkffkj;gkfkfk
X-jfjfjjfjffjfjfj
Q-jfjfjfjf
X-fjfjfjf;fjfnfjf;af' FROM DUAL;

两个输出:
| ID|匹配|
| --|--|
| 1 |Q-fjfjfjfj;公司简介杰菲菲菲X-fjfjfjf;fjfnfjf; af|
| 2 |Q-fjfjfjfj;公司简介X-jfjfjfjffjfjfj|
| 2 |Q-jfjfjf X-fjfjfjf;fjfnfjf; af|
fiddle

相关问题