我们可以使用索引值分隔字符串,以便可以分离包含组合字符的输入,并且最终输出将是可读的字符串。
Input = 20140610182213
Expecting Output = 2014-06-10 18:22:13
答案 0 :(得分:2)
我通常使用替代类似的任务:
my $input = '20140610182213';
$input =~ s/(....)(..)(..)(..)(..)(..)/$1-$2-$3 $4:$5:$6/;
print $input;
另一种可能性是使用substr
:
my $input = '20140610182213';
my @delims = ('-', '-', ' ', ':', ':');
substr $input, $_, 0, pop @delims for 12, 10, 8, 6, 4;
print $input;
答案 1 :(得分:1)
您可能希望unpack
:
my ( $year, $mon, $mday, $hour, $min, $sec ) = unpack "A4 A2 A2 A2 A2 A2", "20140610182213";
say "$year-$mon-$mday $hour:$min:$sec";
答案 2 :(得分:1)
让我们全部modern:
use strict;
use warnings;
use feature qw(say);
my $input = "20140610182213";
$input =~ /(?<year>\d{4})
(?<month>\d{2})
(?<day>\d{2})
(?<hour>\d{2})
(?<minute>\d{2})
(?<second>\d{2})/x;
say "$+{year}-$+{month}-$+{day} $+{hour}:$+{minute}:$+{second}";
我在这里使用命名的背引用。在Perl从很早开始,你总是有数字后引用,我可以用括号设置:
$input =~ /(\d{4})(\d{2})(\d{2})/;
my $year = $1;
my $month = $2;
my $day = $3;
每个括号分组都是后引用。这是直接从sed
。
在Perl 5.10中,现在可以使用命名的反向引用。它们的格式为(?<name>regex)
,其中name
是后引用的名称,regex
是正则表达式。要引用它们,请使用$+{name}
,其中name
是您的后引用名称。
最大的好处是你现在有了背面参考的实际名称,你不必担心$2
的含义:
$input =~ /(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})/;
my $year = $+{year};
my $month = $+{month};
my $day = $+{day};
现在,我们在正则表达式中使用x
标志。这允许我们有多行正则表达式:
$input =~ /(?<year>\d{4})
(?<month>\d{2})
(?<day>\d{2})/x; #The /x flag
my $year = $+{year};
my $month = $+{month};
my $day = $+{day};
如果你不熟悉语法,一开始可能会有点困难。然而,关于这一点的一个好处是它记录了正在发生的事情,并使维护更容易。一旦你的眼睛适应光线,就很容易看到发生了什么并发现错误。
另一种可能性是使用Time::Piece将日期时间转换为Perl可以直接操作的内容:
use strict;
use warnings;
use feature qw(say);
use Time::Piece;
my $input = "20140610182213";
my $date_object = Time::Piece->strptime($input, "%Y%m%d%H%M%S");
printf "%04d-%02d-%02d %02d:%02d:%02d\n",
$date_object->year,
$date_object->mon,
$date_object->mday,
$date_object->hour,
$date_object->minute,
$date_object->second;
同样,正在发生的事情已有详细记录。您可以看到输入字符串是什么,并且您可以轻松地引用字符串的每个部分,甚至可以更改格式。如果你想要这个月的名字怎么办?使用$date_object->month
。
对于简单的解析并且再也不使用它,第一种方式可能是最好的。但是,通过使用Time::Piece
,您现在可以查看两个日期之间的天数(例如,您的日期/时间戳的年龄?)。
答案 3 :(得分:1)
我认为使用与sprintf
的全局pattrn匹配是最整洁的:
my $dt = sprintf '%s%s-%s-%s %s:%s:%s', '20140610182213' =~ /../g;
print $dt;
<强>输出强>
2014-06-10 18:22:13
答案 4 :(得分:0)
如果您希望分配给变量的值(例如$ y,$ m,$ d等)以供日后使用:
perl -E '($y,$m,$d,$H,$M,$S)="20140610182213"=~/(....)(..)(..)(..)(..)(..)/;say "$y-$m-$d $H:$M:$S"'
答案 5 :(得分:0)
只需使用Time::Piece
use strict;
use warnings;
use Time::Piece;
my $string = "20140610182213";
my $date = Time::Piece->strptime($string, "%Y%m%d%H%M%S");
print $date->strftime("%Y-%m-%d %H:%M:%S"), "\n";
输出:
2014-06-10 18:22:13