使用Perl正则表达式重新排列时间戳



我想用Perl正则表达式重新安排时间戳,尽可能减少代码。时间戳的原始格式如下:

2011/12/29 20:19:45

我所需要做的就是转换它,使前面的年份在月份/日期之后,如下所示:

12/29/2011 20:19:45

我能够通过下面的3行代码实现这一点。我只是想知道是否有一种方法可以用更少的代码做到这一点。特别是,我试图取消中间一行,将$1保存到中间变量中,并直接在正则表达式中从第一个替换中指定$1作为第二个替换,但这导致了错误:"在串联(.)或字符串中使用未初始化的值$1。"

如果第二行不能去掉,那么这似乎也不能归结为一行?

#my $ts = '2011/12/29 20:19:45'; #input to a subroutine
$ts =~ s/^(d{4})///;
my $year = $1;
$ts =~ s/ //$year /;

给你:

$ts =~ s|^(d{4})/(d{2})/(d{2})(.+)$|$2/$3/$1$4|;

请注意,上面的表达式要求时间戳的恰好为,月份和天数为2位,年份为4位。但你可以让它更短但更可靠:

$ts =~ s|^(d+)/(d+)/(d+)(.+)$|$2/$3/$1$4|;

这一个将正确处理像1998年1月12日12:34:56这样的时间戳。

使用Back References可以获得所需的格式-

[jaypal:~/Temp] echo "2011/12/29 20:19:45" | 
perl -pe 's@([0-9]{4})/([0-9]{2})/([0-9]{2})@$3/$1/$2@'
29/2011/12 20:19:45

对于更通用的时间戳操作,您可能希望通过strptime/strftime往返。在这种情况下,这只是字段的重新排序,但对于更复杂的情况,例如将月份编号转换为名称,则需要strftime

my @t = strptime "2011/12/29 20:19:45", "%Y/%m/%d %H:%M:%S";
say strftime "%d/%m/%Y %H:%M:%S", @t;    #  29/12/2011 20:19:45
say strftime "%d %b %Y, %H:%M:%S", @t;   #  29 December 2011, 20:19:45

最新更新