Pet*_*ete 3 string perl datetime type-conversion
这里是 Perl 新手。我有一个解析日志文件的 Perl 脚本 (v5.26.1)。由于我无法控制的原因,日志中每个日期的格式如下:
"yyyy.mm.dd.hh.mm.ss"
Run Code Online (Sandbox Code Playgroud)
例如:
"2022.09.19.16.35.00"
Run Code Online (Sandbox Code Playgroud)
请注意,年始终为四位数字,而月、日、小时、分钟和秒始终为两位数。(例如九月是09)
我需要将此字符串转换为 DateTime 对象以进行比较。我以为这个练习会很容易,但是五个小时和大量谷歌搜索之后毫无结果,我还差得很远。这是我的第一次尝试:
#!/usr/bin/perl
use warnings;
use strict;
sub transStrToDTime
{
# Example format of a date: "2022.09.19.16.35.00"
my $str = @_; # Only one input argument
use DateTime qw( );
my ($y,$m,$d,$h,$m,$s) = $str =~ /^([0-9]{4}).([0-9]{2}).([0-9]{2}).([0-9]{2}).([0-9]{2}).([0-9]{2})\z/
or die;
my $dt = DateTime->new(
year => $y,
month => $m,
day => $d,
hour => $h,
minute => $m,
second => $s,
time_zone => 'local'
);
printf("=-=-=-=-=-=-=->>> \"$dt\"\n");
}
my $str="2022.09.19.16.35.00";
transStrToDTime($str);
Run Code Online (Sandbox Code Playgroud)
代码有语法错误:
me@ubuntu:/home/me# ./toyPerl.pl
Died at ./toyPerl.pl line 16.
me@ubuntu:/home/me#
Run Code Online (Sandbox Code Playgroud)
其中第 16 行是:
my ($y,$m,$d,$h,$m,$s) = $str =~ /^([0-9]{4}).([0-9]{2}).([0-9]{2}).([0-9]{2}).([0-9]{2}).([0-9]{2})\z/
Run Code Online (Sandbox Code Playgroud)
Uggggggghhhhhhhhh...在阅读了这个主题并变得更加困惑之后,我决定手动进行转换。我想我所要做的就是:
split()上的字符串.这是这次尝试:
#!/usr/bin/perl
use warnings;
use strict;
my $str="2022.09.19.16.35.00";
my @spl = split('.', $line);
#Lets look at the tokens before we build the DateTime object:
for(my $i = 0; $i <= $#spl; $i++){
print("$i) $spl[$i] \n");
}
Run Code Online (Sandbox Code Playgroud)
输出:
me@ubuntu:/home/me# ./toyPerl.pl
me@ubuntu:/home/me#
Run Code Online (Sandbox Code Playgroud)
没有输出...意味着split()分裂"2022.09.19.16.35.00" 成零个标记? 那么不是$str字符串吗?那么它可能是什么数据类型呢?
#!/usr/bin/perl
use warnings;
use strict;
my $str="2022.09.19.16.35.00";
printf("Verifying that \$str is a string:\n");
printf("---> ${ref($str)}\n");
Run Code Online (Sandbox Code Playgroud)
输出:
me@ubuntu:/home/me# ./toyPerl.pl
Verifying that "2022.09.19.16.35.00" is a string:
Can't use string ("") as a SCALAR ref while "strict refs" in use at ./2222toyPerl.pl line 7.
me@ubuntu:/home/me#
Run Code Online (Sandbox Code Playgroud)
其中第 7 行是这一行:
printf("---> ${ref($str)}\n");
Run Code Online (Sandbox Code Playgroud)
我很困惑。错误消息似乎表明我的字符串不是标量。但我认为 Perl 中的字符串是标量?(“标量通常是数字或字符串。"" ”)为什么第 7 行字符串被缩减为空字符串 ( )?
天啊。这篇文章代表了半天的工作。有人能发现我在第一种方法中的语法错误吗?为什么我不能split()串起来"2022.09.19.16.35.00"?不是字符串什么的吗?谢谢。
当你把
my $str = @_;
Run Code Online (Sandbox Code Playgroud)
这意味着您将数组放入标量上下文中,并且在标量上下文中,数组返回其大小。您想要的是使用列表上下文:
my ($str) = @_;
Run Code Online (Sandbox Code Playgroud)
或者更好的是,使用惯用语shift:
my $str = shift; # automatically uses @_ inside a subroutine
Run Code Online (Sandbox Code Playgroud)
您还使用两个$m变量。将其中之一更改为其他内容。修改后的代码按预期工作:
use strict;
use warnings;
sub transStrToDTime {
my ($str) = @_; # Only one input argument
use DateTime qw( );
my ($y,$M,$d,$h,$m,$s) = $str =~ /^([0-9]{4}).([0-9]{2}).([0-9]{2}).([0-9]{2}).([0-9]{2}).([0-9]{2})\z/
or die;
my $dt = DateTime->new(
year => $y,
month => $M,
day => $d,
hour => $h,
minute => $m,
second => $s,
time_zone => 'local'
);
printf("=-=-=-=-=-=-=->>> \"$dt\"\n");
}
my $str="2022.09.19.16.35.00";
transStrToDTime($str);
Run Code Online (Sandbox Code Playgroud)
输出:
=-=-=-=-=-=-=->>> "2022-09-19T16:35:00"
Run Code Online (Sandbox Code Playgroud)
在第一个方法中您所说的语法错误实际上并不是语法错误。只是您的代码表明die正则表达式匹配是否失败。请注意,die没有消息并不能提供太多信息。您可能想在那里放一些更有用的东西。
在第二种情况下,当您拆分 时'.',您使用的是通配符.,而不是文字句点。因此,整个字符串都被消耗掉了,没有留下任何东西。你可以尝试split /\./一下。
在第三种情况下,我不知道你在这里做什么:${ref($str)}你试图取消引用ref?的返回值。返回值ref只是一个字符串,例如ARRAYor SCALAR。这不是你使用的方式ref。如果您想知道变量包含什么内容,请使用Data::Dumper:
use Data::Dumper;
print Dumper $str;
# will print $VAR1 = 1; in your first program ($str is the size of the array @_)
Run Code Online (Sandbox Code Playgroud)
另外,这一行:
printf("=-=-=-=-=-=-=->>> \"$dt\"\n");
Run Code Online (Sandbox Code Playgroud)
printf能用的时候就不要用print。printf有特殊用途。my $str = @_;
Run Code Online (Sandbox Code Playgroud)
除了 TLP 所说的一切之外,您还可以使用
use DateTime::Format::Strptime qw( );
my $format = DateTime::Format::Strptime->new(
pattern => '%Y.%m.%d.%H.%M.%S',
strict => 1,
time_zone => 'local',
on_error => 'croak',
));
my $dt = $format->parse_datetime( $str );
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
189 次 |
| 最近记录: |