将HH:MM转换为十进制小时

时间:2016-05-11 12:07:10

标签: regex perl awk

我正在尝试将格式为HH:MM的文本文件中的某些时间戳转换为数字格式(例如,12:30 - > 12,5 1 Perl正则表达式,以便将来更容易处理。

我在这个主题上相当新,所以我正在努力学习MM部分而且我不知道如何转换它。目前我有这样的事情:

while ( <FILE> ) {
    $line = $_;
    $line =~ s/([0[0-9]|1[0-9]|2[0-3]):([0-5][0-9])/$2,$1/g;
    print $line;    
}  

1)在我的语言环境中,逗号,用于小数点。想象一下.所以这意味着12个半,或12.5。

6 个答案:

答案 0 :(得分:5)

我不会使用正则表达式进行转换。它可以用非常简单的数学来完成。使用搜索模式解析时间,然后通过类似的方式传递它。

sub to_decimal {
    my $time = shift;

    my ($hours, $minutes) = split /:/, $time;
    my $decimal = sprintf '%.02d', ($minutes / 60) * 100 ;

    return join ',', $hours, $decimal;
}

如果你在这样的循环中运行它:

for (qw(00 01 05 10 15 20 25 30 35 40 45 50 55 58 59)) {
    say "$_ => " . to_decimal("12:$_");
}

你得到:

00 => 12,00
01 => 12,01
05 => 12,08
10 => 12,16
15 => 12,25
20 => 12,33
25 => 12,41
30 => 12,50
35 => 12,58
40 => 12,66
45 => 12,75
50 => 12,83
55 => 12,91
58 => 12,96
59 => 12,98

答案 1 :(得分:1)

这将实现您的需求。它使用可执行替换将时间字符串替换为小时和分钟值的表达式。 tr/./,/r用于将所有点转换为逗号

use strict;
use warnings 'all';

while ( <DATA> ) {
    s{ ( 0[0-9] | 1[0-9] | 2[0-3] ) : ( [0-5][0-9] ) }{
        sprintf('%.2f', $1 + $2 / 60) =~ tr/./,/r
    }gex;
    print;
}  

__DATA__
00:00
05:17
12:30
15:59
23:59

输出

0,00
5,28
12,50
15,98
23,98

答案 2 :(得分:1)

perl -ple 's|(\d\d):(\d\d)|{$2/60 + $1}|eg'

您的语言环境应该使用逗号,我想

答案 3 :(得分:0)

您可以使用egrepawk

$ echo 12:30 | egrep -o '([0[0-9]|1[0-9]|2[0-3]):([0-5][0-9])' | awk -F":" '{printf $1+$2/60}'
12.5

答案 4 :(得分:0)

您只需调整替换以使其有效:

$line =~ s/(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9])/"$1," . substr( int($2)\/60, 2)/eg;

e修饰符导致替换内容为eval,因此您可以根据捕获组内容将预期结果写为公式的类型。请注意,substr调用会删除分数字符串表示中的前导0,

如果您需要将自己限制为给定的小数位数,请使用sprintf格式化除法的结果:

$line =~ s/(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9])/"$1," . substr( sprintf('%.2f', int($2)\/60), 2)/eg;

答案 5 :(得分:0)

假设您的LC_NUMERIC是正确的:

while (<FILE>) {
    use locale ':not_characters';
    my $line = $_;
    $line =~ s!\b([01][0-9]|2[0-3]):([0-5][0-9])\b!$1 + $2/60!eg;
    print $line;
}