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

时间:2012-01-05 16:56:39

标签: regex 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 /;

3 个答案:

答案 0 :(得分:5)

你去吧:

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

请注意,上面的表达式要求时间戳为完全 2位数字表示月份和日期,4位数字表示年份。但是你可以让它更短更可靠:

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

这个会正确处理时间戳,如1/12/98 12:34:56。

答案 1 :(得分:1)

使用后退参考,您可以获得所需的格式 -

[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

答案 2 :(得分:0)

对于更通用的时间戳操作,您可能希望通过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