I want to check if ALL words from $words exist in one or more $sentences, word order is not important.
Words will only contain [a-z0-9].
Sentences will only contain [a-z0-9-].
My code so far, it almost work as expected:
$words = array("3d", "4");
$sentences = array("x-3d-abstract--part--282345", "3d-speed--boat-430419", "beautiful-flower-462451", "3d-d--384967");
foreach ($words as $word) {
$sentences_found = array_values(array_filter($sentences, function($find_words) use ($word) {return strpos($find_words, $word);}));
}
print_r($sentences_found);
If you run this code here http://3v4l.org/tD5t5 , you'll get 4 results, but in reality it should be 3 results
Array
(
[0] => x-3d-abstract--part--282345
[1] => 3d-speed--boat-430419
[2] => beautiful-flower-462451 // this one is wrong, no "3d" in here, only "4"
[3] => 3d-d--384967
)
How can I do this?
Also is there any better way to do this than strpos?
Regex?
Regex is maybe slow for this job because sometimes there will be 1000's of $sentences (don't ask why).
You could use an intersection of found sentences per word:
$found = array();
foreach ($words as $word) {
$found[$word] = array_filter($sentences, function($sentence) use ($word) {
return strpos($sentence, $word) !== false;
});
}
print_r(call_user_func_array('array_intersect', $found));
Or, approach from $sentences
:
$found = array_filter($sentences, function($sentence) use ($words) {
foreach ($words as $word) {
if (strpos($sentence, $word) === false) {
return false;
}
}
// all words found in sentence
return true;
});
print_r($found);
One important thing to mention is that your search criteria was wrong; instead of strpos($sentence, $word)
you should explicitly compare against false
, otherwise you will miss a match at the start of a sentence.