【问题标题】:How do I extract a pattern from a table in Oracle 11g?如何从 Oracle 11g 中的表中提取模式?
【发布时间】:2011-09-20 12:48:22
【问题描述】:

我想在 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 将这 2 个查询粘合在一起,但它既混乱又笨拙。如何将它们组合成 1 个查询。谢谢。

更新:模式“BC”的示例数据:

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

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

【问题讨论】:

  • 有趣...您能否发布数据样例和所需结果的示例?

标签: regex oracle


【解决方案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。

【讨论】:

    【解决方案2】:

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

    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)
            )
        ) 
    

    【讨论】:

      猜你喜欢
      • 2019-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      • 2011-12-07
      • 2014-05-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多