如何从Oracle 11g中的表中提取模式?

时间:2011-06-22 15:54:03

标签: regex oracle

我想使用Oracle 11g中的正则表达式从列中提取文本。我有2个查询可以完成这项工作,但我正在寻找一种(更清洁/更好)的方法。可能将查询组合成一个或新的等效查询。他们在这里:

查询1:识别与模式匹配的行:

select column1 from table1 where regexp_like(column1, pattern);

查询2:从匹配的行中提取所有匹配的文本。

select regexp_substr(matching_row, pattern, 1, level) 
from dual
connect by level < regexp_count(matching_row, pattern);

我使用PL / SQL将这两个查询粘合在一起,但它很混乱而且很笨拙。如何将它们组合成1个查询。谢谢。

更新:模式'BC'的样本数据:

row 1: ABCD
row 2: BCFBC
row 3: HIJ
row 4: GBC

预期结果是4行'BC'的表格。

2 个答案:

答案 0 :(得分:1)

您也可以在一个查询中执行此操作,不需要函数/过程/包:

WITH t1 AS (
SELECT 'ABCD' c1 FROM dual
UNION
SELECT 'BCFBC' FROM dual
UNION
SELECT 'HIJ' FROM dual
UNION
SELECT 'GBC' FROM dual
)
SELECT c1, regexp_substr(c1, 'BC', 1, d.l, 'i') thePattern, d.l occurrence
  FROM t1 CROSS JOIN (SELECT LEVEL l FROM dual CONNECT BY LEVEL < 200) d
WHERE regexp_like(c1,'BC','i')
   AND d.l <= regexp_count(c1,'BC');

C1    THEPATTERN           OCCURRENCE
----- -------------------- ----------
ABCD  BC                            1
BCFBC BC                            1
BCFBC BC                            2
GBC   BC                            1

SQL>

我随意限制了在200,YMMV搜索的出现次数。

答案 1 :(得分:0)

实际上,在一个查询中有一种优雅的方法可以执行此操作,如果您不介意运行一些额外的里程。请注意,这只是一个草图,我没有运行它,你可能需要更正其中的一些拼写错误。

create or replace package yo_package is
  type word_t  is record (word varchar2(4000));
  type words_t is table of word_t;
end;
/

create or replace package body yo_package is

  function table_function(in_cur in sys_refcursor, pattern in varchar2) 
  return words_t
    pipelined parallel_enable (partition in_cur by any)
  is
    next varchar2(4000);
    match varchar2(4000);
    word_rec word_t;
  begin
    word_rec.word = null;

    loop

    fetch in_cur into next;
    exit when in_cur%notfound;

    --this you inner loop where you loop through the matches within next
    --you have to implement this 
    loop
        --TODO get the next match from next     
        word_rec.word := match;
        pipe row (word_rec);    
    end loop;

    end loop;

  end table_function;

end;
/


select  *
from table(
    yo_package.table_function(
        cursor(
            --this is your first select
            select column1 from table1 where regexp_like(column1, pattern)
        )
    )