2017-04-04 83 views
0

我从客户端获取数据,其中日期值有时包含额外数字。这里有几个例子: 2/13/201733246当日期值后面有额外值时从字符串中提取日期

2/15/20179714

3/7/201712718

这些值加载到一个临时表作为一个字符串,但我需要提取日期部分并将其作为日期加载到最终目标表中。

我曾尝试使用正则表达式,并可以选择日期的模式,但我坚持从那里。我怎样才能选择不属于日期的数值并去除它们?我可以用oracle regexp来做到这一点吗?

我也尝试在月份和日期部分添加前导0,并且可以确定何时只是一位数字,但是如何将0与原始数字一起添加?

如果我使用substr,如果月份和日期都是2位数字,但两者都是单个数字,则失败。

任何帮助将非常感谢!

+0

的问题是,如果你有一个可以依靠的模式。例如,你是否总是用“/”分隔日,月?总是用四位数字写年? – Aleksej

+0

是的,日期总是MM/DD/YYYY。不一致的部分是今年之后的比特。也就是说,MM/DD部分可能是1位或2位。 –

回答

3

这可能是一个办法:

with inputData(str) as (
    select '2/13/201733246' from dual union all 
    select '2/15/20179714' from dual union all 
    select '3/7/201712718' from dual 
) 
select str, regexp_substr(str, '^[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}') 
from inputData 

这可以被重新用不同的,更紧凑,办法,但我相信这是易于阅读。

正则表达式看起来是一个或两个数字([0-9]{1,2})后面跟一个/的序列的两倍,然后是一年中完全4位数的序列([0-9]{4})

的另一种方式,不使用正则表达式,可能是以下几点:

substr(str, 1, instr(str, '/', 1, 2) +4) 

这看起来对/的第二个发生,并给出从第一个字符的字符串到第二/加4个字符年。

结果:

SQL> with inputData(str) as (
    2  select '2/13/201733246' from dual union all 
    3  select '2/15/20179714' from dual union all 
    4  select '3/7/201712718' from dual 
    5 ) 
    6 select str, 
    7   regexp_substr(str, '^[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}') str1, 
    8   substr(str, 1, instr(str, '/', 1, 2) +4) str2 
    9 from inputData; 

STR     STR1  STR2 
-------------------- ---------- ---------- 
2/13/201733246  2/13/2017 2/13/2017 
2/15/20179714  2/15/2017 2/15/2017 
3/7/201712718  3/7/2017 3/7/2017 

无论你决定使用,如果你需要得到的结果DATE格式的方式,你必须使用一个to_date上面显示的字符串转换结果。

例如, regexp_substr(str, '^[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}') 应该成为 to_date(regexp_substr(str, '^[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}'), 'mm/dd/yyyy')

+0

这是完美的!我使用了你提供的正则表达式,不仅起作用,而且学到了一些可以引导的东西。谢谢! –

+2

由于问题是如何提取DATE,您应该通过TO_DATE来包围表​​达式,即'TO_DATE(regexp_substr(str,'^ [0-9] {1,2}/[0-9] {1,2}/[0-9] {4}'),'MM/DD/YYYY')'为了得到一个'DATE'结果。 –

+0

感谢您提及TO_DATE部分。我没有完全证明我已经完成了这个省略,但是可能会帮助其他人寻求完成这项工作。 –