1

我已经非常努力地使用 Perl 正则表达式找到这种特定转换(这些日期格式)的示例,但无济于事。有人可以帮我在这些格式之间转换日期吗?

Dec 26 2012 12:00AM ==>  201212126

以下是我最初的尝试,但运行速度太慢(显然,我使用 substr 5 次,这太荒谬了)。

# Format the input time to yyyymmdd from 'Dec 26 2012 12:00AM' like format.
sub formatTime($)
{
    #Get passed in value of format 'Dec 26 2012 12:00AM'.
    my $col = shift; 

    if (substr($col, 4, 1) eq " "){
        substr($col, 4, 1) = "0";
    }

    return substr($col, 7, 4).$months{substr($col, 0, 3)}.substr($col, 4, 2);
}

注意:这是为了工作,用于将输入文件转换为非常大的数据库摄取,不幸的是,python 在平台上不受支持,这是我选择的脚本语言。我尝试制作自己的 Perl 正则表达式,但我只是没有时间在做其他部分时阅读并弄清楚它。昨天我已经浪费了大部分时间来编写 Perl 脚本并在其余部分中快速学习,这种转换只是花了我太长时间。

4

3 回答 3

19

我建议您使用模块DateTime + DateTime::Format::Strptime

#!/usr/local/bin/perl
use strict;

use DateTime;
use DateTime::Format::Strptime;

my $strp = DateTime::Format::Strptime->new(
      pattern => '%b %d %Y %l:%M%p',
      locale  => 'en_US',
);

# convert date to 
my $date = 'Dec 26 2012 10:10AM';
my $dt   = $strp->parse_datetime( $date );
printf "%s -> %s\n", $date, $dt->strftime("%Y-%m-%d %H:%M");

输出

Dec 26 2012 10:10AM -> 2012-12-26 10:10
于 2012-09-21T13:12:11.957 回答
1

那么,有哪些Dec 26 2012 12:00AM有趣的部分呢?

Dec    26   2012     12:00      AM
$month $day $year $hour:$minute $pm

所以我们只需定义简单的正则表达式,捕获有趣的信息,并将它们放入适当的变量中:

my ($month, $day, $year, $hour, $minute, $pm)
  = ($string =~ m{
        (\w{3})   \s+             # 3 word characters
        (\d{1,2}) \s+             # 1 or 2 digits
        (\d{4})   \s+             # 4 digits
        (\d{2}) : (\d{2}) (AM|PM) # the hour, minute and AM/PM context
      }ix;
    );

接下来,我们将月份设为数字并使用 AM/PM 信息:

$month = {
  Jan => 1,
  Feb => 2,
  ...
  Dec => 12,
}->{$month} or die "Unknown month $month";

$hour += $pm =~ /pm/i ? 12 : 0; # if $pm contains "pm", then add 12 h

然后,我们通过以下方式构建一个适当的零填充字符串sprintf

my $format_string = "%04d%02d%02d" . ($include_hour ? "%02d%02d" : "");
my $date = sprintf $format_string,
  $year, $month, $day, $hour, $minute;

如果您有野心,您也可以轻松添加时区;-)

当输入是 like 时,这种方法会产生奇怪的结果16:00PM,因为这会输出2800为时间,这显然是错误的。如果这可能是一个问题,请pm仅进行更正if $hour <= 12。但是,仅当$include_hour设置为真值时才重要。

于 2012-09-21T13:12:21.290 回答
-1
use strict;
use warnings;

my $str = "Dec 26 2012 12:00AM";

my %months = (
    Jan => "01",
    [...]
    Dec => "12"
);
$str =~ /^(\w{3}) (\d{1,2}) (\d{4})/; 

print $3.$months{$1}.$2;
于 2012-09-21T13:28:28.903 回答