Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Variable/multiple matches using grep

by Anonymous Monk
on Aug 11, 2006 at 16:20 UTC ( #566876=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks
I am trying to use grep to query a CSV file against incoming data from a html form. There are four drop down fields and I want to be able to match against the CSV data depending on what is selected. For example the user could only select drop downs one and four.

@result = grep /$one.$two.$three.$four/, @data;

The above works but if $one has the value of 1 it matches against every instance on 1 in the CSV file. Is there a way to limit the match as /^$one$/ would work for example?

Any help, advice or alternatives would be greatly appreciated. Thanks

Replies are listed 'Best First'.
Re: Variable/multiple matches using grep
by jhourcle (Prior) on Aug 11, 2006 at 16:49 UTC
    Is there a way to limit the match as /^$one$/ would work for example?

    Most likely, yes. However, you've not shown what the expected values are for the data that you're matching against, nor what qualifies as a match, nor how you tell when two & three are empty.

    Personally, I use something where an indentifier may be made up of 4 parts ... (provider, source, instrument, detector), and they're identified by strings of the format "PROV.SOURCE.INST.DET", each of the individual identifiers is alphanumeric:

    my $pattern = qr( '^'. ( join '\.', map { defined($_) ? $_ : '[^.]*' } @query{ qw( provider source instrument detector ) } ). '$' ); my @matches = grep { $_ =~ m/$pattern/ } @data;

    Note -- I'm using '[^.]*' as opposed to '[^.]+', as not all of the identifiers have all 4 items populated, and would be empty for those slots.

Re: Variable/multiple matches using grep
by idsfa (Vicar) on Aug 11, 2006 at 17:39 UTC

    I do not recommend using regular expressions to parse a CSV. What happens if part of the input includes a comma? In the Massive Overkill department, I would suggest using DBD::CSV:

    use DBI; $dbh = DBI->connect("DBI:CSV:") or die "Cannot connect: " . $DBI::errstr; $dbh->{'csv_tables'}->{'data'} = { 'file' => 'data.csv'}; # Find the matching rows in the table $sth = $dbh->prepare('SELECT * FROM data ' . 'WHERE column1 = ? AND column2 = ? ' . 'AND column7 = ? AND column5 = ?', $one, $two, $three, $four) or die "Cannot prepare: " . $dbh->errstr(); $sth->execute() or die "Cannot execute: " . $sth->errstr(); my($id, $name); $sth->bind_columns(undef, \$id, \$name); while ($sth->fetch) { # Print the name and id of each matching row printf("Found result row: id = %s, name = %s\n", defined($id) ? $id : "NULL", defined($name) ? $name : "NULL"); } $sth->finish(); $dbh->disconnect();

    The intelligent reader will judge for himself. Without examining the facts fully and fairly, there is no way of knowing whether vox populi is really vox dei, or merely vox asinorum. — Cyrus H. Gordon
      Thanks will have a look at the DBD::CSV module. I would strip out any comma's but here the values are in drop downs so I can specify these.
Re: Variable/multiple matches using grep
by andyford (Curate) on Aug 11, 2006 at 16:45 UTC
    Seems like we need more info to help you. Can you post more code?
    What is @data? What are $one, $two, $three, $four?
    What are the requirements for @result?
      What is @data?
      @data is the contents of the csv file in an array.
      What are $one, $two, $three, $four?
      This is the incoming data form the four drop downs in a html page
      What are the requirements for @result?
      A simple specific match against the incoming data and the CSV data. If drop downs $one and $four have been selected I want to display the reults.The data is mostly numerical

      Testing against constent incoming data (for example $one $two $three $four) is fine as I can match the incoming data against where I want to look for it in the CSV @data and I know there is always something incoming.
      But I don't know how to do this for say $one and $two or $two and $four etc which is why I was looking at grep.
Re: Variable/multiple matches using grep
by ahmad (Hermit) on Aug 11, 2006 at 16:43 UTC

    CSV file is comma delemited file , you could loop through the file and do what you want , for example :

    # open CSV file open(FH,"myfile.csv") or die $!; # Loop through file content while (my $line = <FH>) { # split each line so ( $data[0] == first col , $data[1] == seconds + col ... so on ) my @data = split(/,/$line); # now you can test if something matched or not if ( ... ) { # Do Something here # if you want to end the loop after the first match , we just +use last : last; } } # close File handle close(FH);


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://566876]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (9)
As of 2017-10-20 22:48 GMT
Find Nodes?
    Voting Booth?
    My fridge is mostly full of:

    Results (268 votes). Check out past polls.