【问题标题】:regexp_substr all occurence of doc. XXXregexp_substr 所有出现的 doc。 XXX
【发布时间】:2021-01-30 18:38:47
【问题描述】:

这里是一个示例代码:

set define off;
drop table brol;

create table brol
(
br varchar2(4000)
);

INSERT INTO brol ( br ) VALUES ( 'Proposition de décret institutionnalisant l assemblée citoyenne et le conseil citoyen, déposée par Madame Schyns (Doc. 221 (2019-2020) N° 1 et 1bis)
Proposition de décret spécial modifiant les articles 2, 5, 6 et 7 du décret spécial du 19 juillet 2018 instituant la consultation populaire, déposée par Madame Schyns (Doc. 222 (2019-2020) N° 1)
Proposition de modification du Règlement du Parlement de Wallonie visant à institutionnaliser les assemblées citoyennes et conseils citoyens, déposée par Madame Schyns (Doc. 223 (2019-2020) N° 1)
Rapporteur : Monsieur Sahli
Proposition de décret spécial modifiant les articles 2, 5, 6 et 7 du décret spécial du 19 juillet 2018 instituant la consultation populaire en vue d octroyer un droit d initiative aux commissions délibératives composées de députés et de citoyens tirés au sort, déposée par Madame Schyns, Messieurs Desquesnes, Antoine et Bastin (Doc. 278 (2020-2021) N° 1)
Désignation d un Rapporteur 
Discussion - Votes
' );

commit;

select * from brol;

当我执行下一个查询时:

select REGEXP_SUBSTR(br,'Doc. ([[:alnum:]]+\.?)') from brol;

我有结果:

Doc. 221

这是迈出的第一步,我很高兴找到它... 但我也需要作为回报:

Doc. 222 
Doc. 223
Doc. 278 

我不能同时拥有所有 3 个.. 您能帮我找出我在 regexp_substr 中忘记的内容吗?

select REGEXP_SUBSTR(br,'Doc. ([[:alnum:]]+\.?)',1,1) from brol;

文档。 221

select REGEXP_SUBSTR(br,'Doc. ([[:alnum:]]+\.?)',1,2) from brol;

文档。 222

select REGEXP_SUBSTR(br,'Doc. ([[:alnum:]]+\.?)',1,3) from brol;

文档。 223

select REGEXP_SUBSTR(br,'Doc. ([[:alnum:]]+\.?)',1,4) from brol;

文档。 278

有没有办法知道我会找到多少? ==> 不,这是不可能的..

我找到了带有函数https://stackoverflow.com/a/23683522/10710461的方法

create or replace function regexp_substr_mr (

p_data clob, p_re varchar ) 将 varchar 返回为 v_cnt 编号; v_results varchar(4000); 开始 v_cnt := regexp_count(p_data, p_re, 1,'m'); 如果 v_cnt

返回 v_results; 结束;

但我无法适应它......

谢谢,

研发

【问题讨论】:

  • 该函数运行良好,但不是我的调用... select regexp_substr_mr(br,'Doc. ([[:alnum:]]+\.?)' ) from brol;它正在工作!

标签: oracle plsql regexp-substr


【解决方案1】:

您有正确的查询,只需使用 connect by 查找所有内容,

select REGEXP_SUBSTR(br,'Doc. ([[:alnum:]]+\.?)',1,level) 
  from brol
connect by REGEXP_SUBSTR(br,'Doc. ([[:alnum:]]+\.?)',1,level) is not null;

【讨论】:

  • 如果表中只有一行,这将起作用;如果有多行,那么这将产生成倍增加的重复行数,因为CONNECT BY 子句与前一行不相关。
  • @MT0,你是对的,这从来不是 OP 最初问题的一部分。你领先了一步,这很好,但我很清楚它并不适用于所有行,如果需要,它肯定可以为所有行完成。
  • 如果 OP 在 12c 或更高版本上,则可以使用 cross applylateral 轻松完成
【解决方案2】:

有没有办法知道我会找到多少?

使用REGEXP_COUNT:

SELECT REGEXP_COUNT( br, 'Doc\.\s+\d+' ) AS num_docs
FROM   brol;

哪些输出:

| NUM_DOCS | | --------: | | 4 |

您的函数似乎输出了一个 CR-NL 分隔的文档列表。相反,您可以使用:

SELECT RTRIM(
         REGEXP_REPLACE( br, '.*?(Doc\.\s+\d+\.?|$)', '\1' || CHR(13) || CHR(10), 1, 0, 'n' ),
         CHR(13) || CHR(10)
       ) AS docs
FROM   brol

哪些输出:

|文档 | | :------- | |博士。 221 | |博士。 222 | |博士。 223 | |博士。 278 | | :------- |

如果您希望将值放在单独的行中(并且您的 brol 表中可以有多行),那么您可以使用:

WITH docs ( br, doc, lvl, num_docs ) AS (
  SELECT br,
         REGEXP_SUBSTR( br, 'Doc\.\s+\d+\.?', 1, 1 ),
         1,
         REGEXP_COUNT( br, 'Doc\.\s+\d+\.?' )
  FROM   brol
UNION ALL
  SELECT br,
         REGEXP_SUBSTR( br, 'Doc\.\s+\d+\.?', 1, lvl + 1 ),
         lvl + 1,
         num_docs
  FROM   docs
  WHERE  lvl < num_docs
)
SELECT doc
FROM   docs
WHERE  lvl <= num_docs;

哪些输出:

|文档 | | :------- | |博士。 221 | | :------- | |博士。 222 | | :------- | |博士。 223 | | :------- | |博士。 278 | | :------- |

db小提琴here

【讨论】:

    【解决方案3】:

    为简单起见,我在您的表中添加了另一列 - ID(哪种类型唯一标识每一行)。

    SQL> desc brol
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     ID                                                 NUMBER
     BR                                                 VARCHAR2(4000)
    

    我还通过修改您发布的INSERT 在表格中添加了另一行;它包含两个“文档”。价值观。

    最后,这样的查询可能会返回你想要的:

    SQL> select id,
      2    regexp_substr(br, 'Doc\.\s+\d+.?', 1, column_value) result
      3  from brol cross join table(cast(multiset(select level from dual
      4                                           connect by level <= regexp_count(br, 'Doc\.')
      5                                          ) as sys.odcinumberlist))
      6  order by id, result;
    
            ID RESULT
    ---------- ----------
             1 Doc. 221
             1 Doc. 222
             1 Doc. 223
             1 Doc. 278
             2 Doc. 666
             2 Doc. 777
    
    6 rows selected.
    
    SQL>
    

    【讨论】:

      【解决方案4】:

      功能很完美..我的电话不是...

      select regexp_substr_mr(br,'Doc. ([[:alnum:]]+\.?)' ) from brol;
      

      它正在工作。 谢谢大家的回答。我会检查究竟是什么“连接”选项,因为我不知道。我在一个包中,所以我很容易添加一个功能。

      【讨论】:

        猜你喜欢
        • 2021-06-17
        • 2012-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-19
        • 1970-01-01
        • 1970-01-01
        • 2019-12-09
        相关资源
        最近更新 更多