解析不同日期格式的通用方法

时间:2015-05-31 11:40:32

标签: regex perl

我有几种不同的日期格式要解析,例如:

$date1 = '^(\d\d),(\d\d) (\d\d):(\d\d):(\d\d)'; # DD,MM HH:MM:SS
$date2 = '^(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)'; # YYYY-MM-DD HH:MM:SS

我想留下变量

($year, $day, $month, $hour, $minute, $second)

要正确填充。我可以使用以下模式捕获Perl中的第一个日期格式:

($day, $month, $hour, $minute, $second) = $log_line =~ /$date1/;
$year = current_year; # guess as date format has no year value

但要捕获第二个日期,我需要重新排列变量的顺序。我不想在每种类型的日期的订购中进行硬编码,但我知道信息必须包含在某处。

我希望这个程序具有可扩展性和可维护性;我的程序是否有一个简单的解决方案来适应不同的格式?

编辑:我意识到订单必须存储在某处,我正在寻找最简洁的选择。

2 个答案:

答案 0 :(得分:2)

您可以使用命名捕获组立即解决问题:

if ( $str =~ /(?<year>\d\d\d\d)-(?<month>\d\d)-(?<day>\d\d)/ ) {
  $year = $+{year};
  $month = $+{month};
  $day = $+{day};
}

使用cpan中的各种DateTime :: Format模块可以解决更常见的问题。

答案 1 :(得分:1)

您可以使用核心Time::Piece模块来解析日期,

use Time::Piece;

my @arr = (
  Time::Piece->strptime(Time::Piece->new->year ."01,02 13:24:01", "%Y%d,%m %H:%M:%S"),
  Time::Piece->strptime("2015-02-01 13:24:01", "%Y-%m-%d %H:%M:%S"),
);

for my $t (@arr) {
  my ($year, $day, $month, $hour, $minute, $second) = 
    ($t->year, $t->mday, $t->mon, $t->hour, $t->min, $t->sec);

  print "$year, $day, $month, $hour, $minute, $second\n";
}