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

So here is the deal. I have a program that pulls 3 things from the STDIN... userid and two dates. These dates are then fed into DATE::SIMPLE and DATE::RANGE. I then look at all the files in a given directory and parse through these files for any occurences of the userid... if the userid is found, I then look at the date on this line and check if it is in the range of the two STDIN dates. If so, I write this line to a file. The majority of this program works, I am just getting tripped up on one line.... if ($record =~ m/$userinput/g). I use this piece of code to check the line in the file for the userid (or patient) given at STDIN. This line always returns false.

I have tried an alternate method using index, however it to always returns false. Popping the comma delimited line out into an array and directly comparing is a time consuming option as I allow the user to put in multiple types of input (i.e. patient or userid which are both different fields). Any quick fixes are greatly appreciated.

Thanks,
Nick

Full Code:
use Date::Range; use Date::Simple (); print "Enter the userid or patient name (partials accepted): "; $userinput = <STDIN>; print "Enter the start date: "; $dateinput1 = <STDIN>; print "Enter the end date: "; $dateinput2 = <STDIN>; $date1 = Date::Simple->new($dateinput1); + # converts user inputted dates to simple d +ates $date2 = Date::Simple->new($dateinput2); $range = Date::Range->new($date1, $date2); $dirname = "../normalized/"; opendir(DIR, $dirname) or die "can't opendir $dirname"; while ( defined ($file = readdir DIR) ) { next if $file =~ /^[\.nSo]/; + # ensures that folders with n, S or o arent + processed $ORIGINALNAME = "../normalized/" . "$file"; $REPORTNAME = "../normalized/" . $userinput . "-" . $dateinput +1 . "_" . $dateinput2 . ".csv"; open (LOGFILE, $ORIGINALNAME) or die "can't open $ORIGINALNAME +"; while ($record = <LOGFILE>) { + # While reads records line by line from beg +inning to end of file @stringasarray = split(",", $record); + # Takes comma delimited line and breaks in +to array $cutdate = substr ($stringasarray[4],0,10); + # Identifies date field and chops the time o +ff the end $date3 = Date::Simple->new($cutdate); + # converts the date to a simple date if ($record =~ m/$userinput/g) { print "TEST2!"; if ($range->includes($date3)) { + # tests if date from file is within the use +r inputed dates print "TEST!"; #open (REPORT, ">>$REPORTNAME") or die ("Canno +t open"); # Open the report file for writing #print REPORT $record; + # Print record to the file } } exit; } } + # Close files close(LOGFILE); close (REPORT); closedir(DIR);

Replies are listed 'Best First'.
Re: reg ex. problem - 2 variables
by grep (Monsignor) on Oct 04, 2006 at 20:03 UTC
    The problem you are asking about:
    You don't chomp the input from <STDIN>. So your $userinput contains a newline on the end. So your regex looks for the pattern only if it's followed by \n.

    Other than that:
    You will run into problems when running without use strict, which makes me guess you are not using use warnings.

    Don't comment code self-explanatory code.
    Ex.

    open (REPORT, ">>$REPORTNAME") or die ("Cannot open"); # Open the rep +ort file for writing
    Comments are for other programmers. If someone working on this program can't figure out you're opening a file, then there is a problem.


    grep
    One dead unjugged rabbit fish later

      I'd add "Don't comment code so far over in the eastern hemisphere that you need magic or jet travel to get there." All those comments are on the ends of lines and padded so far to the right that on most monitors they would never be seen.

      I'd amplify your "Don't comment code self-explanatory code." comment: if you need to comment every line then the code you are writing is too tricky! Remember, it's at least twice as hard to debug something as it is to write it, so if you are writing the cleverest code you can, you can't debug it!


      DWIM is Perl's answer to Gödel
        so far to the right that on most monitors they would never be seen
        this might make a good poll. who keeps their terminals at 80 columns these days, and/or codes in an editor that doesn't have soft-wrapping?
      Perfect... who would have thought I'd overlook that. I really appreciate the help. -Nick
Re: reg ex. problem - 2 variables
by GrandFather (Saint) on Oct 04, 2006 at 20:05 UTC

    No way we can help until you provide some code we can run. Start with the following template and add data to reproduce your failure:

    use strict; use warnings; my $userinput = 'Blah'; while (my $record = <DATA>) { print "Matched user input against $record" if $record =~ m/$userin +put/g; } __DATA__ Blegh Blah <- that should match blah <- and that won't Yuck

    Prints:

    Matched user input against Blah <- that should match

    DWIM is Perl's answer to Gödel
Re: reg ex. problem - 2 variables
by graff (Chancellor) on Oct 05, 2006 at 02:07 UTC
    A couple of suggestions:
    • Run the script with the three user inputs as command line args, and get their values from @ARGV. It really does make life easier for the user, and it's easier to code (e.g. you don't need to chomp the argv strings):
      use strict; use Date::Simple; use Date::Range; my $Usage = "Usage: $0 userid start-date end-date (dates should be mm/dd/yyyy)\n"; # (is that the date format you wa +nt?) @ARGV == 3 or die $Usage; my ( $userinput, $dateinput1, $dateinput2 ) = @ARGV; # if the user gives unusable values in @ARGV, the script can # do "die $Usage" for those cases as well.
    • The name of the REPORT file never changes, so you should open it for output just once, before you go into the first while loop.