Regexp_Substr问题

时间:2018-01-24 22:41:21

标签: sql regex oracle

我必须用一些非常糟糕的字符来解析一个注释字段,我需要从一些内部术语中提取日期。

基本上这些字段看起来像这样,这是4个不同的注释我想要拉出日期:

Ltr Cert Expires  ****01/15/17***
Ltr Cert Expires  ***01/5/2010***
Ltr Cert Expires  **01/10/11***
Ltr Cert Expires  *******01/15/01***

我对regexp_substr并不是很熟悉,但我在这里探讨了一下,并没有看到很多符合我要求的例子。

有什么想法吗?也许有人建议阅读Regexp for Oracle?我对这个功能很陌生,有时候代码有点莫名其妙。

1 个答案:

答案 0 :(得分:0)

这可能是一种非常不言自明的方式。

它会查找一个或两个数字([0-9]{1,2})的序列,后跟一个'/'(\/),依此类推。

这可以用许多不同的,更紧凑或更尖锐的方式重写,例如检查内容是否真的代表日期,但是如果你假设每一行(对于你的样本数据)总是只包含一个日期,在样本数据的一种格式中,这就足够了:

with test(t) as (
    select 'Ltr Cert Expires  ****01/15/17***' from dual union all
    select 'Ltr Cert Expires  ***01/5/2010***' from dual union all
    select 'Ltr Cert Expires  **01/10/11***' from dual union all
    select 'Ltr Cert Expires  *******01/15/01***' from dual
)
select regexp_substr(t, '[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{2,4}')
from test

给出:

01/15/17
01/5/2010
01/10/11
01/15/01

仅举一个不同方法的例子,在这些数据上,下面给出了相同的结果:

regexp_substr(t, '([^\*]+)', 1, 2)

这将搜索至少一个与'*'不同的字符的序列,但会返回第二个匹配项(第四个参数的值为2)。第一次出现的是第一次'*'之前的所有内容,因此第二次出现的是第一个和第二个'*' s序列之间的字符串部分。

在这种情况下,无论是否为日期,都会返回您拥有的任何字符串。

with test(t) as (
    select 'Ltr Cert Expires  ****01/15/17***' from dual union all
    select 'Ltr Cert Expires  ***01/5/2010***' from dual union all
    select 'Ltr Cert Expires  **01/10/11***' from dual union all
    select 'Ltr Cert Expires  *******01/15/01***' from dual union all
    select 'Ltr Cert Expires  *******Not a date, but ...***' from dual    
)
select regexp_substr(t, '[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{2,4}') as str1,
       regexp_substr(t, '([^\*]+)', 1, 2) as str2
from test

给出:

STR1       STR2
---------- ------------------------------
01/15/17   01/15/17
01/5/2010  01/5/2010
01/10/11   01/10/11
01/15/01   01/15/01
           Not a date, but ...
相关问题