0

I have the folowing regex verified by regex coach

(\d+)\.(\d+)\.(\d+) (\d+):(\d+):(\d+)

this matches the dd.mm.yyyy hh:mm:ss format, but in Perl I don't receive anything

My array contains these two entries

foo 24.03.2014 19:18:57 foobar foo bar
bar 24.03.2014 15:19:00 asdfasrwe jlkj 

Here is my Perl program

use Try::Tiny;

foreach(@array) 
{
    try {
        my ($day, $month, $year,$hours, $minutes, $seconds) = ($_ =~ m/(\d+)\.(\d+)\.(\d+) (\d+):(\d+):(\d+)/);
        my $time= "$hours:$minutes:$seconds";
        my $date= "$day.$month.$year";
    } catch {
         warn "caught error: $_";
    };
    print "Time: $time, Date: $date\n";
}

The output is

Time: , Date: 
Time: , Date: 

As with regex coach, my regex is approved, and no exception is shown. I don't see my error. Where is the problem?

on regex101 - it seems legitimate

Borodin
  • 126,100
  • 9
  • 70
  • 144
MemLeak
  • 4,456
  • 4
  • 45
  • 84

3 Answers3

6

Are 'my $time' and 'my $date' local to the try block? Can you print the values from within the try block?

Anthony
  • 3,492
  • 1
  • 14
  • 9
  • It seems like i've ended up in a bad scoping problem. you pointed me in the right direction! thank you – MemLeak Mar 25 '14 at 16:44
4

Had you applied use strict to your program wou would have seen that the $time and $date variables that you are printing haven't been declared, and so are different from the ones being defined within the try block.

Please always use strict and use warnings at the top of every Perl program you write. It is a simple measure that will reveal many simple mistakes like this.

By the way there is nothing in your try block that could cause a fatal error, so it may as well be written without the use of the Try::Tiny module.

use strict;
use warnings;

use Try::Tiny;

my @array = (
  'foo 24.03.2014 19:18:57 foobar foo bar',
  'bar 24.03.2014 15:19:00 asdfasrwe jlkj', 
);

for (@array) {
    my ($time, $date);
    try {
        my ($day, $month, $year, $hours, $minutes, $seconds) = /(\d+)\.(\d+)\.(\d+) (\d+):(\d+):(\d+)/;
        $time = "$hours:$minutes:$seconds";
        $date = "$day.$month.$year";
    }
    catch {
         warn "caught error: $_";
    };
    print "Time: $time, Date: $date\n";
}

output

Time: 19:18:57, Date: 24.03.2014
Time: 15:19:00, Date: 24.03.2014
Borodin
  • 126,100
  • 9
  • 70
  • 144
1

The answer as already stated is to include use strict; and use warnings at the top of each and every script that you make: Why use strict and warnings?

Also, you're currently pulling out the individual time and date information, but then throwing it away to build your full date and time. You could skip a step there and just use 2 capture groups to pull the date and time from the start.

Additionally, you'll eventually want to be exposed to Time::Piece for working with date/times:

use strict;
use warnings;

use Time::Piece;

my @array = (
    'foo 24.03.2014 19:18:57 foobar foo bar',
    'bar 24.03.2014 15:19:00 asdfasrwe jlkj', 
);

for (@array) {
    if (my ($date, $time) = $_ =~ m/(\d+\.\d+\.\d+) (\d+:\d+:\d+)/) {
        print "Time: $time, Date: $date\n";
    }
}

for (@array) {
    if (/([\d.]{10} [\d:]{8})/) {
        my $t = Time::Piece->strptime($1, "%d.%m.%Y %H:%M:%S");
        print $t, "\n";
    }
}
Community
  • 1
  • 1
Miller
  • 34,962
  • 4
  • 39
  • 60