regexp_substr用于获取正确的结果

时间:2018-03-16 17:56:15

标签: sql regex oracle

我试图使用regexp_substr从列列表字符串中获取每个正确的列名。

查询如下:

select regexp_substr(v_keep, '(^|[(,) ]*)' || r.column_name || '($|[(,) ]+)', 1, 1, 'i')
from dual;

但结果不正确。

v_keep可以是任何列名列表,如abc,abc_abc,abc1或(abc,abc_abc,abc1)。

r.column_name可以像abc或ab。

- 如果输入v_keep是(abc,abc_abc,abc1)并且r.column_name是    ab,它将返回null。

- 如果输入v_keep是(abc,abc_abc,abc1)并且r.column_name是    abc,它将返回列名称abc。

任何人都可以通过修改regexp_substr中的模式来帮助我修复它吗?

3 个答案:

答案 0 :(得分:2)

为什么不使用caselike

select (case when replace(replace(v_keep, '(', ','), '(', ',')) like '%,' || r.column_name || ',%'
             then r.column_name
        end)

我不建议将列表存储在以逗号分隔的字符串中,但如果是,则这是识别列表中各个元素的一种方法。

答案 1 :(得分:0)

这很简单,你只需要添加一个子表达式,这样就可以拉出你想要的字符串部分。 (子表达式是括号中正则表达式的一部分。)在这种情况下,最后一个参数是2,因为您希望匹配的部分对应于第二组括号。

regexp_substr(v_keep, '(^|[(,) ]*)(' || r.column_name || ')($|[(,) ]+)', 1, 1, 'i', 2)
不过,戈登的解决方案会有更好的表现。

编辑:工作示例 -

with testdata as (select '(abc, abc_abc, abc1)' as v_keep, 'abc' as column_name from dual)
select regexp_substr(v_keep, '(^|[(,) ]*)(' || r.column_name || ')($|[(,) ]+)', 1, 1, 'i', 2)
from testdata r;

答案 2 :(得分:0)

由于这是PL / SQL代码,以查看某个值是否在字符串中,请尝试这样做,这样可以避免命中数据库和调用REGEXP的开销。只要保持它的直线SQL。我讨厌嵌套的REPLACE调用,但我试图避免使用REGEXP_REPLACE,尽管如果你使用它可以在一个调用中完成。

set serveroutput on;
set feedback off;

declare 
  v_keep  varchar2(50) := '(abc, abc_abc, abc1)';
  compare varchar2(10) := 'abc_';
begin
  if instr(',' || replace(replace(replace(v_keep, ' '), '('), ')') || ',', ',' || compare || ',') > 0 then
    dbms_output.put_line('Column ''' || compare ||''' IS in the keep list');
  else
    dbms_output.put_line('Column ''' || compare ||''' IS NOT in the keep list');
  end if;  
end;