perl regex用于缩短时间戳中的微秒

时间:2015-01-20 19:09:02

标签: regex perl

如何在时间戳中使用正则表达式删除/剪切点(。)后的所有内容?我想用输出来查找下面代码中的时差

  $_ = '2015/01/13 13:59:21.267-05:00';
  s/\.\d*//;
  print $_, "\n";

当前输出:

2015/01/13 13:59:21-05:00

期望的输出:

2015/01/13 13:59:21

查找时差的代码:

use strict;
use warnings;
use Time::Piece;

my $str1 = '2015/01/13 13:58:01.267-05:00';
my $str2 = '2015/01/13 13:59:21.267-05:00';

my @times = map Time::Piece->strptime((s/\.\d*//), '%Y/%m/%d %H:%M:%S'), $str1, $str2;
my $delta = $times[1] - $times[0];
print $delta->pretty;

3 个答案:

答案 0 :(得分:5)

替换运算符不返回修改后的字符串。如果您希望这样做,则需要指定/r修饰符。

map Time::Piece->strptime((s/\.\d*//r, ...), ...

如果你不能要求Perl 5.14+,你需要更多罗嗦的东西。

map { ( my $s = $_ ) =~ s/\.\d*//; Time::Piece->strptime($s, ...) } ...

(如果你没有复制,你最终会修改传递给map的变量,我认为这是一种非常糟糕的做法。)

写一个小子可能会更好。

sub remove_subsecs { ( my $s = $_[0] ) =~ s/\.\d*//; $s }

map Time::Piece->strptime(remove_subsecs($_), ...), ...

或者,您可以使用更好的DateTime(可能在DateTime :: Format :: Strptime的帮助下)。它不仅支持小秒秒亚秒,还可以防止你在处理日期和时间时常犯很多错误。

答案 1 :(得分:1)

(s/\.\d*//)返回导致错误的替换次数:

my @times = map Time::Piece->strptime((s/\.\d*//), '%Y/%m/%d %H:%M:%S'), $str1, $str2;

使用/ r将在perl 5.14 +中具有所需的效果:

my @times = map Time::Piece->strptime( s/\..*//r, '%Y/%m/%d %H:%M:%S'), $str1, $str2; 

或者在perl 5.14之前:

my @times = map { local $_ = $_; s/\..*//; Time::Piece->strptime( $_, '%Y/%m/%d %H:%M:%S') } $str1, $str2; 

答案 2 :(得分:0)

如果你要求正则表达式删除点之后的所有内容,那么它就是:澄清一下,如果你只是想要'。'之前的所有内容。对于字符串:'2015/01/13 13:59:21.267-05:00';

$_=~/\A(.*?)\./is;

$ 1 =点之前的所有内容。