r_mehmed has asked for the wisdom of the Perl Monks concerning the following question:

Monks! a.newbie

i'm working on a small web site where a text input should be pattern matched and all date formats such as(dd/mm/yyyy | dd-mm-yyyy) should converted into say :'01st January 2003'. I managed to do that(with the help of the Monastery) using memory parenthesis($1,$2 etc). The problem is i can apply it to the code only once,thus it matches and converts only the first match... this is the code:
#!perl use CGI; $query = new CGI; $source = $query->param('input'); print $query->header, $query->start_html('10222161'), $query->h1({-align=>center},'CAD Assignment 1B'), $query->p({-align=>center},'The corrected text is: '), $query->hr; $source =~ m!(\d{1,2})(\/|\-)(\d{1,2})(\/|\-)(\d{2,4})!g; my $day = $1; my $month = $3; my $year = $5; if($day == 1 or $day == 21 or day == 31){ $day .='st'; } elsif ($day == 2 or $day == 22){ $day .='nd'; } elsif ($day == 3 or $day == 23){ $day .= 'rd'; } else { $day .= 'th'; } if($month == 01){ $month = 'January'; } elsif ($month == 2){ $month = 'February'; } elsif ($month == 3){ $month = 'March'; } elsif ($month == 4){ $month = 'April'; } elsif ($month == 5){ $month = 'May'; } elsif ($month == 6){ $month = 'June'; } elsif ($month == 7){ $month = 'July'; } elsif ($month == 8){ $month = 'August'; } elsif ($month == 9){ $month = 'September'; } elsif ($month == 10){ $month = 'October'; } elsif ($month == 11){ $month = 'November'; } else { $month = 'December'; } print $query->p({-align=>center},"$day $month $year"), $query->hr, $query->i({-align=>center},'10222161'), $query->end_html;

Many thanks in advance!

Replies are listed 'Best First'.
Re: pattern matching through a whole document
by BrowserUk (Patriarch) on Nov 01, 2002 at 13:51 UTC

    One way to do this is to use the substitution operator s/// (see perlfunc and perlop) and use the e modifier to executed a small 'program' in the second part of the operator. By using arrays to store your months and day endings, you greatly simplify the logic of the code.

    #!perl use strict; my @months = qw( -- January February March April May June July August +September October November December); my @dayends = qw( -- st nd rd th th th th th th th th th th th th th t +h th th th st nd rd th th th th th th th st); while(my $date = <DATA>) { chomp $date; $date =~ s!(\d{1,2})(\/|\-)(\d{1,2})(\/|\-)(\d{2,4})! $1 . $dayend +s[$1] . ' ' . $months[$3] . ' ' . $5 !eg; print $date, $/; } __DATA__ 3/3/2002 5/11/2002 31-07-2002 1-4-02 21-2-02 31-12-2002

    Gives output

    c:\test>209700 3rd March 2002 5th November 2002 31st July 2002 1st April 02 21st February 02 31st December 2002 c:\test>

    Maybe you can adapt this to your purposes.


    Nah! Your thinking of Simon Templar, originally played by Roger Moore and later by Ian Ogilvy
      many thanks, your code has been of great help!i know all this isn't thah hard to do,but it takes time. will do my best not to ask stupd Q all the time...

      r_mehmed
      stupid:gravity
Re: pattern matching through a whole document
by Thelonius (Priest) on Nov 01, 2002 at 13:49 UTC
    $query->h1({-align=>center},'CAD Assignment 1B'),
    Homework!

    By the way, you should read the chapter on arrays.

    @months = qw(January February March ...);
Re: pattern matching through a whole document
by dingus (Friar) on Nov 01, 2002 at 13:52 UTC
    put the regex and processing in a while loop. I.e.
    while($source =~ m!(\d{1,2})(\/|\-)(\d{1,2})(\/|\-)(\d{2,4})!g) { my $day = $1; my $month = $3; my $year = $5; # process stuff print $query->p({-align=>center},"$day $month $year"), }
    Note:
    1 unless you know there are no confusing spaces in your dates you may wish to have the middle expressions as \s*(\/|\-)\s*
    2 if you use the (?: ) syntax you will not $2 and $4 defined. Then you can do while(($day,$month,$year) =(source=~ /.../g) ) { and assign the values as you test the RE.

    Combining my notes would give you a while line

    while(($day,$month,$year) = ($source =~ m!(\d{1,2})\s*(?:\/|\-)(\d{1,2})\s*\s*(?:\s*(?:\/|\-)\s* +(\d{2,4})!g) ){
    which may or may not be easier to understand.