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

Hi, i have written a script which is not working quite as i would like. It reads in a file of data which it catergorizes and it also has a menu for the user to choose a catergory to look at. My problems are that i have written a do-until loop to go back to the menu once the user has finished looking at one catergory - although it does go back to the menu it doesn't display the data when another option has been selected. My second problem is that in order to catergorize the data i am using regular expression matches - however they are not extracting everything that matches that particular reg exp. Can anyone point out where i have gone wrong?
#! /usr/local/bin/perl -w use strict; my $num_of_params; $num_of_params = @ARGV; if ($num_of_params < 2) { die ("\n You haven't entered enough parameters \n\n"); } open (FH, $ARGV[0]) or die "unable to open file"; open (OUTFILE, ">$ARGV[1]"); # declare some variables. my $line; my @array; my $first=0; my $second=0; my $third; my $fourth; my $fifth; my $others; do { print STDOUT "\nPlease select the catergory of results that you wish t +o see;\n\n \t1. first \n\t2. second \n\t3. third \n\t4. fourth \n\t5. others\n\t6 +. Exit program\n\n"; $choice = <STDIN>; chomp $choice; print "\nIdentifier \t\t%identity \n\n"; while (<FH>) { $line = $_; chomp ($line); @array = (); @array = split (/\s+/, $line); $array[8] =~ s/\%//g; if ((($array[1] =~ m{/:yes\|\w+\|\w+}) || ($array[1] =~ m{/:maybe\|\w ++\|\ w+})) && ($array[8] > 95) && ($choice eq 1)) { $first = "$array[1]\t$array[8]\n"; print $first; print OUTFILE $first; } elsif ((($array[1] =~ m{/:no\|\w+\|\w+}) || ($array[1] =~ m{/:noway\ |\w+\|\w+})) && ($array[8] > 95) && ($choice eq 2)) { $second = "$array[1]\t$array[8]\n"; print $second; print OUTFILE $second; } elsif ((($array[1] =~ m{/:definatley\|\w+\|\w+}) || ($array[1] =~ m{ +/:highly\|\w +\|\w+})) && ($array[8] < 95) && ($choice eq 3)) { $third = "$array[1]\t$array[8]\n"; print $third; print OUTFILE $third; } elsif ((($array[1] =~ m{/:no\|\w+\|\w+}) || ($array[1] =~ m{/:noway \|\w+\|\w+})) && ($array[8] < 95) && ($choice eq 4)) { ; $fourth = "$array[1]\t$array[8]\n"; print $fourth; print OUTFILE $fourth; } elsif (($choice eq 5) && (($array[1] =~ m{/:perhaps\|\w+\|\w+}) || ($ +array[1] =~ m{ /:possibly\|\w+\|\w+}) || ($array[1] =~ m{/:unsure\|\w+\|\w+}) || ($ar +ray[1] =~ m{/: maybe\|\w+\|\w+})) && ($array[8] > 0)) { $others = "$array[1]\t\t$array[8]\n"; print $others; print OUTFILE $others; } elsif ($choice eq 6) { last; } } } until ($choice eq 6); close OUTFILE;
I really hope that someone can teach me something.

Replies are listed 'Best First'.
Re: user input / reg exp's
by janx (Monk) on Jun 14, 2002 at 16:11 UTC
    Hi! You are open'ing the input handle FH on you first argument. So far so good.
    Inside your main event loop (the do {} while stuff) you read in the complete file with:
    while (<FH>) { ... }

    Obviously the second time round (when the user is presented the main menu again) the <FH> is going to fail instantly because the read pointer is at the end of the file from the previous reads. Otherwise you wouldn't have returned from the while loop.
    If the file isn't too large, I would recommend to first (outside the menu loop) read in the whole file (in an array perhaps) and to do you matching on that, rather than reading the file while you match. Another solution would be to seek (perldoc seek) to the beginning of the file each time you get a choice from the user, but that would be lossage (You don't want to read in the file each time you want to read it, do you ;-)?)

    As to your regex problems:
    It generally is a bit hard to help improving a regex if one doesn't know the input data.
    Thus, if you have a decent short example of input data, I'm sure we can work out a solution.


    Hope that helps,
    Kay