tags:

views:

329

answers:

3

I have another csv file where I am trying to do a simple word filter. For example, my text.csv file looks something like this:

name, age, hobbies
Tom, 8, "football, soccer, baseball, wii, star wars, books"
Bill, 9, "football, baseball, ice hockey, basketball"
Sue, 8, "baseball, soccer, volleyball, bicycles, skating"
Mike, 8, "basketball, music, guitar, cartoons, books"
Ella, 9, "soccer, basketball, softball, clothes, books"
Tim, 9, "football, baseball, basketball, wii, cartoons"
Steven, 8, "baseball, soccer, star wars, cartoons, books"

I would like to filter by the third column. For example, if I filter by "wii" I will get rows 1 and 6 sent back:

Tom, 8, "football, soccer, baseball, wii, star wars, books"
Tim, 9, "football, baseball, basketball, wii, cartoons"

If I filter by "wii" or "guitar" I will get rows 1, 4, and 6 sent back.

Tom, 8, "football, soccer, baseball, wii, star wars, books"
Mike, 8, "basketball, music, guitar, cartoons, books"
Tim, 9, "football, baseball, basketball, wii, cartoons"

I'm not good at php and arrays, but I've tried messing around with preg_match - but not sure if something like strpos is better. Here's what I've done but can't get it to work right:

<?PHP
$firstWord = 'wii';
$secondWord = 'guitar';
$file = fopen('text.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) 
{  
list($name[], $age[], $hobbies[]) = $line;
if (preg_match($firstWord, $hobbies[0]) || (preg_match($secondWord,     $hobbies[0]) {
echo $name . ',"' .$age . '",' .$hobbies . "<br> \n";
} else {
    echo "A match was not found.<br> \n";
}}
?>

Any coding help is appreciated. It would also be nice to have the search be case-insensitive. Thanks for reading!

+2  A: 

You're close. Something like this should work:

$file  = fopen('text.csv', 'r');

// You can use an array to store your search words, makes things more flexible.
// Supports any number of search words.
$words = array('wii', 'guitar');    
// Make the search words safe to use in regex (escapes special characters)
$words = array_map('preg_quote', $words);
// The argument becomes '/wii|guitar/i', which means 'wii or guitar, case-insensitive'
$regex = '/'.implode('|', $words).'/i';

while (($line = fgetcsv($file)) !== FALSE) {  
    list($name, $age, $hobbies) = $line;

    if(preg_match($regex, $hobbies)) {
        echo "$name, $age, $hobbies<br />\n";
    }
}
Tatu Ulmanen
Thanks, I got a '{' error but then I changed the last lines to include a second ')' at the end of preg_match. Works great, thanks Tatu! How can I make the search case insensitive so it doesn't matter if I search for 'Guitar' or 'guitar'?
Thomas
@Thomas: `$regex = '/'.implode('|', $words).'/i';` Use the case-insensitive flag **i**
jasonbar
Thanks much jasonbar. You've all helped me out greatly. Much appreciated.
Thomas
A: 

What about case insensitive searches. I'm curious to make this work amonst a list of my outlook contacts. Is there a better function to use than strtolower()??

kalpaitch
A: 

It's probably worth noting here that PHP has CSV handling libraries.

http://php.net/manual/en/function.fgetcsv.php

This returns the next line of the CSV as an array e.g.

// csv file contains "col1,col2,col3"
// array = {'col1', 'col2', 'col3'}
$array = fgetcsv($csv);

Then you can simply use in_array() or a test on $array[column_number] to filter.

I'm not sure if using a regular expression on the line string vs. using array search functions would be faster though, so it's probably worth testing.

Keith Humm