Perl 分隔一个没有分隔符的字符串

Perl 分隔一个没有分隔符的字符串,perl,Perl,我们是否可以使用索引值分离字符串,以便可以分离由组合字符组成的输入,并且最终输出将是可读的字符串 Input = 20140610182213 Expecting Output = 2014-06-10 18:22:13 我通常使用类似任务的替代品: my $input = '20140610182213'; $input =~ s/(....)(..)(..)(..)(..)(..)/$1-$2-$3 $4:$5:$6/; print $input; 另一种可能是使用substr: m

我们是否可以使用索引值分离字符串,以便可以分离由组合字符组成的输入,并且最终输出将是可读的字符串

Input = 20140610182213  
Expecting Output = 2014-06-10 18:22:13

我通常使用类似任务的替代品:

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;

如果希望分配给变量(例如$y、$m、$d等)的值供以后使用:

perl -E '($y,$m,$d,$H,$M,$S)="20140610182213"=~/(....)(..)(..)(..)(..)(..)/;say "$y-$m-$d $H:$M:$S"'

为此,您可能需要
解包

my ( $year, $mon, $mday, $hour, $min, $sec ) = unpack "A4 A2 A2 A2 A2 A2", "20140610182213";

say "$year-$mon-$mday $hour:$min:$sec";
让我们了解你的全部情况:

每个括号分组都是反向引用。这直接取自
sed

在Perl5.10中,现在可以使用命名的反向引用。它们的格式为
(?regex)
,其中
name
是back引用的名称,
regex
是正则表达式。要引用它们,请使用
$+{name}
其中
name
是您的后引用名称

最大的优点是,您现在有了用于反向引用的实际名称,您不必担心
$2
的含义:

$input =~ /(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})/;
my $year  = $+{year};
my $month = $+{month};
my $day   = $+{day};
如果你不熟悉语法,一开始可能会有点难。然而,这其中一个好处是它记录了正在发生的事情,并使维护变得更容易。一旦你的眼睛适应了光线,就很容易看到发生了什么并发现错误


另一种可能是使用将该日期时间转换为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\u object->month


对于简单的解析并且不再使用它,第一种方法可能是最好的。但是,通过使用
Time::Piece
,您现在可以查看两个日期之间的天数(例如,您的日期/时间戳有多大?)

我认为使用与
sprintf
匹配的全局模式是最整洁的:

my $dt = sprintf '%s%s-%s-%s %s:%s:%s', '20140610182213' =~ /../g;
print $dt;
输出

2014-06-10 18:22:13
2014-06-10 18:22:13
只用

产出:

my $dt = sprintf '%s%s-%s-%s %s:%s:%s', '20140610182213' =~ /../g;
print $dt;
2014-06-10 18:22:13
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