【问题标题】:PL/SQL, regexp, connect byPL/SQL、正则表达式、连接方式
【发布时间】:2016-06-21 10:54:52
【问题描述】:

2 示例代码:

      WITH A AS
  (SELECT 'this is a test:12/01/2015  01/05/2018'
    || chr(13)
    ||chr(10)
    || ' this is the 2nd line: 07/07/2017' Description
  FROM dual
  )
SELECT to_date(regexp_substr(A.Description , '\d{1,2}/\d{1,2}/\d{4}',1,level),'MM/DD/YYYY')
FROM A
  CONNECT BY level  <= regexp_count(a.description, '\d{1,2}/\d{1,2}/\d{4}');
/

还有一个:

SELECT DISTINCT REGEXP_SUBSTR ('23,34,45,56','[^,]+',1,LEVEL) as "token"
FROM   DUAL
CONNECT BY REGEXP_SUBSTR ('23,34,45,56','[^,]+',1,LEVEL) IS NOT NULL
order by 1;

谁能解释一下,为什么在第一种情况下我们使用'

【问题讨论】:

  • 在第一个示例中,您也可以使用IS NOT NULL ==> 只需CONNECT BY regexp_substr(a.description, '\d{1,2}/\d{1,2}/\d{4}', 1, level) is not null。在第二个示例中,您可以使用CONNECT BY level &lt;= REGEXP_count ('23,34,45,56','[\,]+') + 1 代替IS NOT NULL。很难说为什么有人选择is not null 而不是regexp_count,在我看来,这可能只是个人喜好。
  • 避免在第二个选择中使用正则表达式来解析分隔列表。它不处理 NULL 列表元素,并且会默默地返回不正确的值。请参阅此处了解更多信息:stackoverflow.com/questions/31464275/…

标签: regex oracle plsql


【解决方案1】:
Introduced in Oracle 10g 

REGEXP_SUBSTR - 返回匹配正则表达式的字符串。

Introduced in Oracle 11g 

REGEXP_COUNT - 返回字符串中正则表达式的出现次数。

不使用关系运算符 '

WITH A AS
      (SELECT 'this is a test:12/01/2015  01/05/2018'
        || chr(13)
        ||chr(10)
        || ' this is the 2nd line: 07/07/2017' Description
      FROM dual
      )
    SELECT to_date(regexp_substr(A.Description , '\d{1,2}/\d{1,2}/\d{4}',1,level),'MM/DD/YYYY')
    FROM A
      CONNECT BY   
      regexp_substr(A.Description , '\d{1,2}/\d{1,2}/\d{4}',1,LEVEL) is not null;

在您的第二个查询中,您可以根据需要使用“

SELECT DISTINCT REGEXP_SUBSTR ('23,34,45,56','[^,]+',1,LEVEL) as "token",LEVEL
        FROM   DUAL
    CONNECT BY LEVEL  <= regexp_count(('23,34,45,56'),'[^,]+');

【讨论】:

    【解决方案2】:

    有时在REGEXP_SUBSTR 的输出中使用IS NOT NULL 找到的行数与REGEXP_COUNT 中的行数相同,然后它们会做同样的事情,这取决于个人喜好:

    SELECT REGEXP_SUBSTR( '1,2,3', '\d+', 1, LEVEL ) AS value
    FROM   DUAL
    CONNECT BY LEVEL <= REGEXP_COUNT( '1,2,3', '\d+' )
    

    SELECT REGEXP_SUBSTR( '1,2,3', '\d+', 1, LEVEL ) AS value
    FROM   DUAL
    CONNECT BY REGEXP_SUBSTR( '1,2,3', '\d+', 1, LEVEL ) IS NOT NULL
    

    两个输出:

    VALUE
    -----
    1
    2
    3
    

    但是,有时匹配的子字符串可以是零宽度(相当于NULL),然后它们不是:

    SELECT REGEXP_SUBSTR( '1,2,,4', '(\d*)(,|$)', 1, LEVEL, 1 ) AS value
    FROM   DUAL
    CONNECT BY LEVEL <= REGEXP_COUNT( '1,2,3', '(\d*)(,|$)' )
    

    输出:

    VALUE
    ------
    1
    2
    (null)
    4
    (null)
    

    和:

    SELECT REGEXP_SUBSTR( '1,2,,4', '(\d*)(,|$)', 1, LEVEL, NULL, 1 ) AS value
    FROM   DUAL
    CONNECT BY REGEXP_SUBSTR( '1,2,,4', '(\d*)(,|$)', 1, LEVEL, NULL, 1 ) IS NOT NULL
    

    输出:

    VALUE
    ------
    1
    2
    

    并停在第一个 NULL 值处。

    要获得所有结果,您要么需要使用REGEXP_COUNT,要么在CONNECT BY 子句中没有REGEXP_SUBSTR() 函数返回NULL 值(因此,在此示例中,我们可以通过提取完整匹配来修复它而不仅仅是捕获组;即REGEXP_SUBSTR( '1,2,,4', '(\d*)(,|$)', 1, LEVEL ) IS NOT NULL)。

    【讨论】:

      猜你喜欢
      • 2014-07-27
      • 2019-06-10
      • 2015-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多