使用 REGEXP_SUBSTR 过滤具有不同长度前缀的部分

问题描述 投票:0回答:1

基本上,我在 PL/SQL 中有一个输入字符串,如下所示:

input varchar2(100) := R985AD5768N2

该字符串由多个信息组成,每个信息前面都有某个前缀,并将每个块连接起来。前缀列表是可变的,在本例中为

R
D5
G
N
。信息可以包含数字和字符,只要没有作为前缀的字符序列即可。此外,某些前缀可能不一定出现在输入字符串内。 我的目标是使用 REGEXP_SUBSTR 按前缀过滤每个块的信息,因此从上面的示例中得到以下结果:

R  -> 985A
D5 -> 768
G  -> NULL
N  -> 2

我的总体想法是分别使用

'R([^R|D5|G|N]+)(R|D5|G|N)?'
形式的模式作为
R
,这意味着我要求我的序列以字符 R 开头,然后使用所有后续字符直到下一个前缀(或字符串末尾)到达了。使用 REGEXP_SUBSTR 的 subexpr 参数,我可以直接选择第二部分,即我正在寻找的信息。

我尝试了几种方法:


REGEXP_SUBSTR(input, 'R([^R|D5|G|N]+)(R|D5|G|N)?', 1, 1, 'c', 1) -- and other prefixes accordingly

很好,除了

R
结果只有 98,我猜是因为 5 出现在 D5 前缀中。

REGEXP_SUBSTR(input, 'R(\w+)(R|D5|G|N)', 1, 1, 'c', 1)

使用正向方法,它将选择最长的方法,这意味着输入在其各自的前缀之后的全部剩余部分。

我尝试了其中的几种变体,例如替换一些括号,但似乎一个关键缺陷仍然是

D5
前缀在其各自的括号中未被识别为文字。 我看到一些方法使用一些前瞻参数,但遗憾的是,据我所知,这些方法不受支持。

关于如何澄清这一点有什么想法吗?

oracle plsql regexp-substr
1个回答
0
投票

您可以使用递归查询并仅查找前缀并找到它们的开始和结束位置,然后后缀将是它们之间的子字符串。

WITH sample_data (value) AS (
  SELECT 'R985AD5768N2' FROM DUAL
),bounds (value, sspos, sepos, espos, eepos) AS (
  SELECT value,
         1,
         2,
         REGEXP_INSTR(value, 'R|G|N|D5', 2, 1, 0),
         REGEXP_INSTR(value, 'R|G|N|D5', 2, 1, 1)
  FROM   sample_data
  WHERE  value LIKE 'R%'
UNION ALL
  SELECT value,
         espos,
         eepos,
         REGEXP_INSTR(value, 'R|G|N|D5', eepos, 1, 0),
         REGEXP_INSTR(value, 'R|G|N|D5', eepos, 1, 1)
  FROM   bounds
  WHERE  eepos > 0
)
SELECT SUBSTR(value, sspos, sepos - sspos) AS prefix,
       CASE WHEN espos = 0
       THEN SUBSTR(value, sepos)
       ELSE SUBSTR(value, sepos, espos - sepos)
       END AS suffix
FROM   bounds

哪个输出:

前缀 后缀
R 985A
D5 768
N 2

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.