SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Enthusiast
    Join Date
    May 2005
    Posts
    50
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Cool String parsing: As long as all words are present, ignore order

    This code below works prefectly as long as the $string, contains any of the strings exactly as in the array. But what if the $string has "camera digital" or "player dvd" (same words, but different order from the array) how can I alter the regex to make itmatch as long all the words are there, independent of the order?

    PHP Code:

    $product_array
    [] = "stereo";
    $product_array[] = "dvd player";
    $product_array[] = "digital camera";

    foreach(
    $product_array as $one_product)
    {
    if (
    preg_match("/$one_product/i"$string$matchesPREG_OFFSET_CAPTURE)) 
    {
    return 
    $matches[0];
    }

    Thank you for any input....

  2. #2
    Programming Team silver trophybronze trophy
    Mittineague's Avatar
    Join Date
    Jul 2005
    Location
    West Springfield, Massachusetts
    Posts
    17,228
    Mentioned
    194 Post(s)
    Tagged
    2 Thread(s)

    variations

    Instead of trying to find a complex solution, why not just add the variations to the array?

  3. #3
    SitePoint Enthusiast
    Join Date
    May 2005
    Posts
    50
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I should have noted that I used a sample array for the post. The array in question is thousand of entries long so to make a variation for all of them would make the array dramatically larger and make the speeeed much slower.

    Thank you for any more input anyone may have.

  4. #4
    Programming Team silver trophybronze trophy
    Mittineague's Avatar
    Join Date
    Jul 2005
    Location
    West Springfield, Massachusetts
    Posts
    17,228
    Mentioned
    194 Post(s)
    Tagged
    2 Thread(s)

    matching words

    I can't think of a way to do this with a more complex regex. Depending on how many words in each array value are being matched, it should be fairly easy to explode() the value and reverse them and use them in the match. eg. maybe something like:
    PHP Code:
    $val_combo = array();

    foreach(
    $product_array as $one_product)
    {
        
    $val_arr explode(' '$one_product);
        if(
    count($val_arr) > 1)
        {
            
    $val_combo[0] = $val_arr[0] . ' ' $val_arr[1];
            
    $val_combo[1] = $val_arr[1] . ' ' $val_arr[0];
        }
        else
        {
            
    $val_combo[0] = $one_product;
        }
        
    $combo_len count($val_combo);
        for(
    $i 0$i $combo_len$i++)
        {
            if (
    preg_match("/$val_combo[$i]/i"$string$matchesPREG_OFFSET_CAPTURE)) 
            {
            return 
    $matches[0]; 
            }
        }

    If there are always only 2 words, you could simplify this a bit. If there are sometimes more than 2 words you could either tweak this a bit or add some recursive re-ordering code to it. But you get the idea. Or you could just match the individual words without rearranging them if that would work.
    IMHO this would be slower than adding them to the original array, but it definately would be easier than manually adding them to the array. You probably should consider putting something together that would add the rearranged values to the array one-time for you.

  5. #5
    Worship the Krome kromey's Avatar
    Join Date
    Sep 2006
    Location
    Fairbanks, AK
    Posts
    1,621
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How about this as your solution:
    Code PHP:
    $product_array[] = "stereo";
    $product_array[] = "dvd player";
    $product_array[] = "digital camera";
     
    foreach($product_array as $one_product)
    {
        $one_product = explode(" ", $one_product);
        $found = false;
        foreach($one_product as $one_word)
        {
            $found = !(stripos($string, $one_word)===false);
            if(!$found) break;
        }
        if($found)
            return $string;
    }
    If you're not using PHP5 (required to use the case-insensitive stripos) then use strtolower to force $string to be all lower-case and then use strpos instead. Getting rid of the regex should improve your performance dramatically (regex is extremely expensive), and since you're not actually making use of the power of regex it is completely unnecessary.
    Last edited by kromey; Jun 19, 2007 at 12:00. Reason: Error in code
    PHP questions? RTFM
    MySQL questions? RTFM

  6. #6
    Programming Team silver trophybronze trophy
    Mittineague's Avatar
    Join Date
    Jul 2005
    Location
    West Springfield, Massachusetts
    Posts
    17,228
    Mentioned
    194 Post(s)
    Tagged
    2 Thread(s)

    no regex

    Good point about the regex. If you need to know the number of times it matched to weight it, you could add a substr_count() line.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •