我必须用一些非常糟糕的字符来解析一个注释字段,我需要从一些内部术语中提取日期。
基本上这些字段看起来像这样,这是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?我对这个功能很陌生,有时候代码有点莫名其妙。
答案 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 ...