Я хочу проверить, существуют ли ВСЕ слова из $ words в одном или нескольких предложениях $, порядок слов не важен.
Слова будут содержать только [a-z0-9].
Предложения будут содержать только [a-z0-9-].
Мой код пока работает почти так, как ожидалось:
$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);
Если вы запустите этот код здесь http://3v4l.org/tD5t5 , вы получите 4 результата, но на самом деле это должно быть 3 результата
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
)
Как я могу это сделать?
Также есть ли лучший способ сделать это, чем strpos?
Regex?
Regex может быть медленным для этой работы, потому что иногда будут тысячи предложений по $ (не спрашивайте почему).
Вы можете использовать пересечение найденных предложений по слову:
$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));
Или подход от $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);
Важно отметить, что ваши критерии поиска были неправильными; вместо strpos($sentence, $word)
вы должны явно сравнить с false
иначе вы пропустите совпадение в начале предложения.
Других решений пока нет …