2013-03-13 115 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信息。