正则表达式在oracle select中排除结果

时间:2020-01-02 12:01:49

标签: sql regex oracle

我从oracle数据库表中获得以下字符串

import os
import glob
NumberofAlphabets = input('Enter Number of Alphabets:')
NF = int(NumberofAlphabets)
Input = 1
while Input < NF+1:
    AlphabetName = input('Enter Alphabet Name:')
    tempF += AlphabetName
    Input += 1
print(tempF)

我正在使用AM-X1-X4-XX5 BI-TG-GF2 G7-FF 从表中选择3列,如下所示:

regexp_substr

当前语句如下

AM|X1|X4
BI|TG|GF2
G7|FF|(null)
到目前为止,一切都很好。现在,我需要以排除字符串“ AM”和“ BI”的方式来转换正则表达式或sql语句。我的select语句应返回下表:

select 
  regexp_substr(c, '[^-]+',1, 1) as p1,
  regexp_substr(c, '[^-]+',1, 2) as p2,
  regexp_substr(c, '[^-]+',1, 3) as p3,
from table;

因此,我尝试如下修改正则表达式,因此它会跳过匹配“ AM”或“ BI”的匹配项

X1|X4
TG|GF2
G7|FF

但是,它不起作用。对于通过调整sql或regex语句来创建第二个表的任何帮助,均表示赞赏

4 个答案:

答案 0 :(得分:2)

不确定任务条件有多严格,但是在现实生活中我会做这样的事情。返回2列,因为仅请求2列

select 
regexp_substr(regexp_replace(c, '^(AM|BI)-',''), '[^-]+',1, 1) as p1,
regexp_substr(regexp_replace(c, '^(AM|BI)-',''), '[^-]+',1, 2) as p2
from table;

但是,当任务是获取前三个“-”分隔的cols然后删除AM / BI时,我将使用以下方式

select
regexp_substr(regexp_replace(substr(c, 1, decode(instr(c, '-', 1, 3), 0, length(c), instr(c, '-', 1, 3)-1)), '(AM-|BI-)'), '[^-]+',1, 1) as p1,
regexp_substr(regexp_replace(substr(c, 1, decode(instr(c, '-', 1, 3), 0, length(c), instr(c, '-', 1, 3)-1)), '(AM-|BI-)'), '[^-]+',1, 2) as p2
from table

我看到的最后一个(也是最痛苦的)情况是,任务是删除前三个“-”分隔的列,然后仅使用regexp过滤掉AM / BI。

with t1 as (select regexp_replace(regexp_substr(c, '[^-]+',1, 1) || '-' || regexp_substr(c, '[^-]+',1, 2) || '-' || regexp_substr(c, '[^-]+',1, 3),'(AM-|BI-)','') c from qq)
select 
regexp_substr(c, '[^-]+',1,1) p1,
regexp_substr(c, '[^-]+',1,2) p2,
from t1;

答案 1 :(得分:0)

一种解决方案是删除这些模式,然后使用当前的逻辑:

select regexp_substr(c, '[^-]+',1, 1) as p1,
       regexp_substr(c, '[^-]+',1, 2) as p2,
       regexp_substr(c, '[^-]+',1, 3) as p3
from (select trim(both '-' from regexp_replace('-' || c || '-', '-AM-|-BI-', '')) as c
      from t
     ) t

Here是db <>小提琴。

答案 2 :(得分:0)

仅使用经典的replace()函数就足够了:

with t as
(
 select replace(replace(c,'AM'),'BI') as c 
   from tab
)
select regexp_substr(c, '[^-]+',1, 1) as p1,
       regexp_substr(c, '[^-]+',1, 2) as p2,
       regexp_substr(c, '[^-]+',1, 3) as p3
  from t

Demo

答案 3 :(得分:0)

您可以使用REGEXP_REPLACE()完成所有操作。对字符串的各个组成部分进行分组,并用所需的部分替换。第一组是AM或BI。第二组是第一组,后跟一个连字符,整个过程可选。第三组是下一个连字符之前的下一组字符,然后是未保存的连字符,然后第四组是不是连字符的下一组字符,其后是字符串的其余部分。将所有内容替换为组3,管道和组4。

假设不需要的字符串“ AM”或“ BI”仅位于第一位置。

with tbl(str) as (
  select 'AM-X1-X4-XX5' from dual union all
  select 'BI-TG-GF2' from dual union all
  select 'G7-FF' from dual
)
select regexp_replace(str, '((AM|BI)-)?([^-]+)-([^-]+).*$', '\3|\4') after
from tbl; 

AFTER                                                                           
---------------------
X1|X4                                                                           
TG|GF2                                                                          
G7|FF                                                                           

3 rows selected.