2013-03-13 96 views
-1

我有麻烦试图匹配日期模式。任何在以下日期是合法的:模式匹配日期

- 121212 
- 4 9 12 
- 5-3-2000 
- 62502 
- 3/3/11 
- 09-08-2001 
- 8 6 07 
- 12 10 2004 
- 4-16-08 
- 3/7/2005 

是什么让这个日期匹配真正具有挑战性的是,今年没有为4个数字(2位数的年份被认为是在21世纪即02 = 2002年),如果月份/日期为一位数月份,则可以用0开始写入月份/日期,并且日期可能会或可能不会被空格,破折号或斜杠分隔。

这是我目前有:
/((((0[13578])|([13578])|(1[02]))[\/-]?\s*(([1-9])|(0[1-9])|([12][0-9])|(3[01])))|(((0[469])|([469])|(11))[\/-]?\s*(([1-9])|(0[1-9])|([12][0-9])|(30)))|((2|02)[\/](([1-9])|(0[1-9])|([12][0-9])))[\/-]?\s*(20[0-9]{2})|([0-9]{2}))/g

这几乎工作,但现在我不能完全肯定,如果我假设的日期和月份的长度。例如,在121212的情况下,我可能会假定该月是1而不是12。此外,由于某些原因,当我打印出$1$2时,它的值相同。在121212的情况下,$11212,$21212$312。不过,我只想$1121212

+0

是年份“00”2000年(技术上是20世纪) – ysth 2013-03-13 02:55:32

+1

有没有问题? – 2013-03-13 03:03:45

+2

对我来说这似乎不可能100%准确:11213可能是1-12-13或11-2-13。两者都是有效的日期。 – uptownnickbrown 2013-03-13 03:06:31

回答

1

该解决方案处理您提供的所有情况。但是这个解决方案并不是万无一失的,因为这个问题含糊不清。例如。我们如何解释日期12502?是1/25/02还是12/5/02?

use 5.010; 
while (my $line = <DATA>) { 
    chomp $line; 
    my @date = $line =~/
     \A 
     ([01]?\d) # month is 1-2 digits, but the first digit may only be 0 or 1 
     [ \-\/]? # may or may not have a separator 
     ([0123]?\d) # day is 1-2 digits 
     [ \-\/]? 
     (\d{2,4}) # year is 2-4 digits 
     \z 
    /x; 
    say join '_', @date; 
} 

__DATA__ 
121212 
4 9 12 
5-3-2000 
12502 
3/3/11 
09-08-2001 
8 6 07 
12 10 2004 
4-16-08 
3/7/2005 
+0

你在评论 – ysth 2013-03-13 21:16:33

+0

中有“日”和“月”落后感谢@ysth。现在修复了。 – stevenl 2013-03-13 23:22:05

1

您的任务不明确,因为您可能无法从mmddyy中的mdd或mdccyy中判断mmd。

您在与/匹配的地方留下了空格或破折号的选项。

您不检查闰年。

这是可行的,但很容易犯错;不要试图用正则表达式来做这件事。

0

这是我可以根据您提供的信息提出的最佳选择。这一切都可能匹配,并有错误检查月/日范围和也是在今年(1900年至二〇九九年)

/(1[012]|0?\d)([-\/ ]?)([12]\d|3[01]|0?\d)\2((19|20)?\d\d)/ 
1

的CPAN模块Time::ParseDateDateTime很可能你在找什么,除了62502模式:

use DateTime; 
use Time::ParseDate; 

foreach my $str (<DATA>) { 
    chomp $str; 
    $str =~ tr{ }{/}; 

    my $epoch = parsedate($str, GMT => 1); 
    next unless $epoch; # skip 62502 

    my $dt = DateTime->from_epoch (epoch => $epoch); 
    print $dt->ymd, "\n"; 
} 

__DATA__ 
121212 
4 9 12 
5-3-2000 
62502 
3/3/11 
09-08-2001 
8 6 07 
12 10 2004 
4-16-08 
3/7/2005 

一旦有DateTime对象,就可以方便地提取yearmonth,并且day信息。