Developer
Developer

Reputation: 6350

Regex to get time in hour minutes and seconds

I am getting a time in this format 12/Jul/2016:13:26:23.

Now I want to get the time in like 13Hour 26Min and 23Seconds.

How can we do this in Perl through a regular expression? I was trying this but I am unable to do this

$line =~ /^.+?\:(.+)/

Please help me in this how we can do this.

Upvotes: 0

Views: 1373

Answers (4)

zdim
zdim

Reputation: 66883

There are some most excellent date-time modules, but given the unusual output format and simple input perhaps a regex is a good solution here.

my ($day, $mon, $year, $hour, $minute, $sec) = 
    $line =~ m{ (\d+) / ([^/]+) / (\d{4}):(\d{2}):(\d{2}):(\d{2}) }x;

where I've used }x global modifier so I can use spaces for readability, and {} delimiters so / can be used unescaped. Now print the captures out as you please.

Or, one can make use of the : delimiter in the relevant part of the input string

my @hms = $line =~ m/:(\d+)/g;
print "@hms\n";

With the string from the question this prints 13 26 23. This captures all consecutive digits following a colon, repeatedly by the /g modifier. So @hms contains: hour, minute, second.

Also, if your format is etched in stone this is simple using split

my @hms = (split /:/, $line)[-3..-1];

where we capture the last three items obtained by splitting on :. If you ever need to capture all parts then use the fact that the pattern specification in split takes a full regex, so

my @parts = split /[:\/]/, $line;

returns (and assigns to @parts) the list 12 Jul 2016 13 26 23.


I'm cheating with \d since it's shorter than [0-9], and it repeats so many times. But note that \d is Unicode aware and it thus matches various kinds of "digits" -- a few hundred various characters. So please replace those \d with [0-9].

Upvotes: 1

Borodin
Borodin

Reputation: 126722

One of the simplest ways of doing this is to scan the date-time string for sequences of "word" characters, which includes all digits and letters plus the underscore character. That will return the values of all the fields and you can do with them what you will

use strict;
use warnings 'all';

my $dt = '12/Jul/2016:13:26:23';

my ($day, $mon, $year, $h, $m, $s) = $dt =~ /\w+/g;

printf "%dHour %dMin and %dSeconds.\n", $h, $m, $s;

output

13Hour 26Min and 23Seconds.

Upvotes: 0

Dave Cross
Dave Cross

Reputation: 69244

The regex solutions that you already have work well, but just for comparison here's how I would do it with Time::Piece.

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use Time::Piece;

my $date_str = '12/Jul/2016:13:26:23';
my $date_fmt = '%d/%b/%Y:%H:%M:%S';

my $date = Time::Piece->strptime($date_str, $date_fmt);

say $date->hour, ' hours, ', $date->minute, ' minutes, ',
    $date->second, ' seconds';

Upvotes: 2

Jens
Jens

Reputation: 69440

This should do the Job:

$line =~ /\d+\/\w+\/\d{4}:(\d+):(\d+):(\d+)/

$1 contains hours $2 minutes and $ three second

Upvotes: 0

Related Questions