Regular expression question

C

Chip

I'm trying to convert a date from an email header like:
Date: Thu, 1 Jan 2004 16:28:41 -0600 (CST)

To the following format:
MM/DD/YYYY

With the following:
if ( $line =~ m/^Date: ..., (.+) (...) /) {
$day = $1;
if ($2 =~ /Jan/){$month = "01";}
if ($2 =~ /Feb/){$month = "02";}
if ($2 =~ /Mar/){$month = "03";}
if ($2 =~ /Apr/){$month = "04";}
if ($2 =~ /May/){$month = "05";}
if ($2 =~ /Jun/){$month = "06";}
if ($2 =~ /Jul/){$month = "07";}
if ($2 =~ /Aug/){$month = "08";}
if ($2 =~ /Sep/){$month = "09";}
if ($2 =~ /Oct/){$month = "10";}
if ($2 =~ /Nov/){$month = "11";}
if ($2 =~ /Dec/){$month = "12";}
$lead_date = "$month/$day/2004";
}

What I need to add is a way to convert 1 to 01, 2 to 02 ect. such as:
if($1 =~ /1/{$day = "01";}

But this would also match 10, 11, 12 and so on,
and if I used "^1?" this would match 11.

What would be the best way to do this?

Thanks
Chip
 
C

Carsten Aulbert

Hi,
With the following:
if ( $line =~ m/^Date: ..., (.+) (...) /) {
$day = $1;
if ($2 =~ /Jan/){$month = "01";}
[snip ]
Here I would simply use a hash (example is incomplete):
my %mon = ('Jan'=>1, 'Feb'=>2,...)

What I need to add is a way to convert 1 to 01, 2 to 02 ect. such as:
if($1 =~ /1/{$day = "01";}
Either try sprintf with %02d, or substr('0'.$day,-2);

HTH

CA
 
G

Gunnar Hjalmarsson

Chip said:
I'm trying to convert a date from an email header like:
Date: Thu, 1 Jan 2004 16:28:41 -0600 (CST)

To the following format:
MM/DD/YYYY

With the following:
if ( $line =~ m/^Date: ..., (.+) (...) /) {
$day = $1;
if ($2 =~ /Jan/){$month = "01";}

That is a terribly clumsy way of converting the month. You may want to
consider something like this:

my %months;
@months{qw/Jan Feb Mar Apr May Jun Jul
Aug Sep Oct Nov Dec/} = ('01'..'12');
$month = $months{$2};
What I need to add is a way to convert 1 to 01, 2 to 02 ect.

Check out the sprintf() function.

http://www.perldoc.com/perl5.8.0/pod/func/sprintf.html
 
J

Jason Hood

What I need to add is a way to convert 1 to 01, 2 to 02 ect. such as:
if($1 =~ /1/{$day = "01";}

But this would also match 10, 11, 12 and so on,
and if I used "^1?" this would match 11.

What would be the best way to do this?

How about

if($1 =~ /(\d{1,1})/){ $day = "0".$1 };

Jason
 
J

James Willmore

I'm trying to convert a date from an email header like:
Date: Thu, 1 Jan 2004 16:28:41 -0600 (CST)

To the following format:
MM/DD/YYYY

With the following:
if ( $line =~ m/^Date: ..., (.+) (...) /) {
$day = $1;
if ($2 =~ /Jan/){$month = "01";}
if ($2 =~ /Feb/){$month = "02";}
if ($2 =~ /Mar/){$month = "03";}
if ($2 =~ /Apr/){$month = "04";}
if ($2 =~ /May/){$month = "05";}
if ($2 =~ /Jun/){$month = "06";}
if ($2 =~ /Jul/){$month = "07";}
if ($2 =~ /Aug/){$month = "08";}
if ($2 =~ /Sep/){$month = "09";}
if ($2 =~ /Oct/){$month = "10";}
if ($2 =~ /Nov/){$month = "11";}
if ($2 =~ /Dec/){$month = "12";}
$lead_date = "$month/$day/2004";
}

What I need to add is a way to convert 1 to 01, 2 to 02 ect. such as:
if($1 =~ /1/{$day = "01";}

But this would also match 10, 11, 12 and so on,
and if I used "^1?" this would match 11.

What would be the best way to do this?


First, I suggest you look over Date::Manip or Date::Calc. Both will easy
the pain of trying to "roll your own". However, below is one way to do
what you're trying to do (not thoroughly tested).

------------------------------------------------------------------
#!/usr/bin/perl -w

my $line = 'Date: Thu, 1 Jan 2004 16:28:41 -0600 (CST)';

my %months = (
'Jan' => '01',
'Feb' => '02',
'Mar' => '03',
'Apr' => '04',
'May' => '05',
'Jun' => '06',
'Jul' => '07',
'Aug' => '08',
'Sep' => '09',
'Oct' => '10',
'Nov' => '11',
'Dec' => '12'
);

my($month,$day);

if ( $line =~ m/^Date: ..., (.+) (...) /) {
my ($d, $m) = ($1,$2);
$day = sprintf "%02d", $d;
$month = $months{$m};
}

print "$month $day\n";

exit;
------------------------------------------------------------------

HTH

--
Jim

Copyright notice: all code written by the author in this post is
released under the GPL. http://www.gnu.org/licenses/gpl.txt
for more information.

a fortune quote ...
Never eat more than you can lift. -- Miss Piggy
 
A

Anno Siegel

Jason Hood said:
How about

if($1 =~ /(\d{1,1})/){ $day = "0".$1 };
^^^^^
How is \d{1,1} different from \d?

Did you test that against a few examples?

Anno
 
T

Tore Aursand

I'm trying to convert a date from an email header like:
Date: Thu, 1 Jan 2004 16:28:41 -0600 (CST)

You really don't want to do that yourself, as there's a module on CPAN
already doing this for you. Date::parse.
What I need to add is a way to convert 1 to 01, 2 to 02 ect. such as:
if($1 =~ /1/{$day = "01";}

perldoc -f sprintf
 
R

Richard A. Evans

Chip said:
I'm trying to convert a date from an email header like:
Date: Thu, 1 Jan 2004 16:28:41 -0600 (CST)

To the following format:
MM/DD/YYYY

What would be the best way to do this?

I think the best way would be to use one of the date modules, but if you are
intent on rolling your own, here's one (admitted a bit obfuscated) way:

use strict;
my %m = map {qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)[$_] =>
1+$_}(0..11);
my $d = 'Thu, 1 Jan 2004 16:28:41 -0600 (CST)';
if ( $d =~ /^(\w+),\s+(\d+)\s+(\w+)\s+(\d+)/ ) {
printf "%02d/%02d/%4d\n", $m{$3}, $2, $4;
}

Regards,

Rick Evans
 
C

Chip

Thanks Carsten,

sprintf was what exactly what I was looking for.

Carsten Aulbert said:
Hi,
With the following:
if ( $line =~ m/^Date: ..., (.+) (...) /) {
$day = $1;
if ($2 =~ /Jan/){$month = "01";}
[snip ]
Here I would simply use a hash (example is incomplete):
my %mon = ('Jan'=>1, 'Feb'=>2,...)

What I need to add is a way to convert 1 to 01, 2 to 02 ect. such as:
if($1 =~ /1/{$day = "01";}
Either try sprintf with %02d, or substr('0'.$day,-2);

HTH

CA
 
C

Chip

Thanks James,

$day = sprintf "%02d", $d;
Works perfect, and was just what I needed.

It was very helpful that you made the module suggestion
and also showed the example code.

Your style of posting is very helpful to myself and
all others using this group.

Again Thanks,
Chip
 
C

Chip

Thanks Tore,

sprintf was what I needed.

Chip
Tore Aursand said:
You really don't want to do that yourself, as there's a module on CPAN
already doing this for you. Date::parse.


perldoc -f sprintf
 
C

Chip

Thanks Richard,
Very interesting suggestion.

I'll give it a try.

Chip
Richard A. Evans said:
Chip said:
I'm trying to convert a date from an email header like:
Date: Thu, 1 Jan 2004 16:28:41 -0600 (CST)

To the following format:
MM/DD/YYYY

What would be the best way to do this?

I think the best way would be to use one of the date modules, but if you are
intent on rolling your own, here's one (admitted a bit obfuscated) way:

use strict;
my %m = map {qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)[$_] =>
1+$_}(0..11);
my $d = 'Thu, 1 Jan 2004 16:28:41 -0600 (CST)';
if ( $d =~ /^(\w+),\s+(\d+)\s+(\w+)\s+(\d+)/ ) {
printf "%02d/%02d/%4d\n", $m{$3}, $2, $4;
}

Regards,

Rick Evans
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top